Альдаципедия
aczwiki
https://acz.skywiki.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0
MediaWiki 1.43.1
first-letter
Медиа
Служебная
Обсуждение
Участник
Обсуждение участника
Альдаципедия
Альдаципедия talk
Файл
Обсуждение файла
MediaWiki
Обсуждение MediaWiki
Шаблон
Обсуждение шаблона
Справка
Обсуждение справки
Категория
Обсуждение категории
Video
Video talk
Campaign
Campaign talk
Модуль
Обсуждение модуля
Шаблон:Str len
10
47
104
2013-03-14T14:34:59Z
wikipedia, ruwikipedia>DR
0
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
95f10258d5214440d2706952656564f216c2e4cc
Шаблон:Str rep
10
81
172
2015-02-28T09:38:11Z
wikipedia, ruwikipedia>Rubinbot II
0
Защищена Шаблон:Str rep: Top used templates to be protected ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессро
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude>
c75032f150c372324c69a6f62ff4ab1492ad4cfa
Шаблон:Lang-fi
10
101
212
2015-06-22T08:43:43Z
wikipedia, ruwikipedia>DimaABot
0
Бот: удаление категории по запросу на [[ВП:РДБ]]
wikitext
text/x-wiki
[[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
16ac91b8e1e294e7687d57c0757c178f9662581c
Модуль:Namespace detect/data
828
23
56
2015-06-27T21:11:34Z
wikipedia, ruwikipedia>Draa kul
0
Защищена Модуль:Namespace detect/data: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Модуль:Namespace detect/config
828
24
58
2015-06-27T21:11:46Z
wikipedia, ruwikipedia>Draa kul
0
Защищена Модуль:Namespace detect/config: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрат…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Модуль:Color contrast/colors
828
35
80
2016-06-19T09:05:16Z
wikipedia, ruwikipedia>Dima st bk
0
Защищена Модуль:Color contrast/colors: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато…
Scribunto
text/plain
return {
aliceblue = 0.92880068253475,
antiquewhite = 0.84646951707754,
aqua = 0.7874,
aquamarine = 0.8078549208338,
azure = 0.97265264954166,
beige = 0.8988459998705,
bisque = 0.80732327372979,
black = 0,
blanchedalmond = 0.85084439608156,
blue = 0.0722,
blueviolet = 0.12622014321946,
brown = 0.098224287876511,
burlywood = 0.51559844533893,
cadetblue = 0.29424681085422,
chartreuse = 0.76032025902623,
chocolate = 0.23898526114557,
coral = 0.37017930872924,
cornflowerblue = 0.30318641994179,
cornsilk = 0.93562110372965,
crimson = 0.16042199953026,
cyan = 0.7874,
darkblue = 0.018640801980939,
darkcyan = 0.20329317839046,
darkgoldenrod = 0.27264703559993,
darkgray = 0.39675523072563,
darkgreen = 0.091143429047575,
darkgrey = 0.39675523072563,
darkkhaki = 0.45747326349994,
darkmagenta = 0.07353047651207,
darkolivegreen = 0.12651920884889,
darkorange = 0.40016167026524,
darkorchid = 0.13413142174857,
darkred = 0.054889674531132,
darksalmon = 0.40541471563381,
darkseagreen = 0.43789249325969,
darkslateblue = 0.065792846227988,
darkslategray = 0.067608151928044,
darkslategrey = 0.067608151928044,
darkturquoise = 0.4874606277449,
darkviolet = 0.10999048339343,
deeppink = 0.23866895828276,
deepskyblue = 0.44481603395575,
dimgray = 0.14126329114027,
dimgrey = 0.14126329114027,
dodgerblue = 0.27442536991456,
firebrick = 0.10724525535015,
floralwhite = 0.95922484825004,
forestgreen = 0.18920812076002,
fuchsia = 0.2848,
gainsboro = 0.71569350050648,
ghostwhite = 0.94311261886323,
gold = 0.69860877428159,
goldenrod = 0.41919977809569,
gray = 0.2158605001139,
green = 0.15438342968146,
greenyellow = 0.80609472611453,
grey = 0.2158605001139,
honeydew = 0.96336535554782,
hotpink = 0.34658438169715,
indianred = 0.21406134963884,
indigo = 0.03107561486337,
ivory = 0.99071270600615,
khaki = 0.77012343394121,
lavender = 0.80318750514521,
lavenderblush = 0.90172748631046,
lawngreen = 0.73905893124963,
lemonchiffon = 0.94038992245622,
lightblue = 0.63709141280807,
lightcoral = 0.35522120733135,
lightcyan = 0.94587293494829,
lightgoldenrodyellow = 0.93348351018297,
lightgray = 0.65140563741982,
lightgreen = 0.69091979956865,
lightgrey = 0.65140563741982,
lightpink = 0.58566152734898,
lightsalmon = 0.4780675225206,
lightseagreen = 0.35050145117042,
lightskyblue = 0.56195637618331,
lightslategray = 0.23830165007287,
lightslategrey = 0.23830165007287,
lightsteelblue = 0.53983888284666,
lightyellow = 0.98161818392882,
lime = 0.7152,
limegreen = 0.44571042246098,
linen = 0.88357340984379,
magenta = 0.2848,
maroon = 0.045891942324215,
mediumaquamarine = 0.49389703310801,
mediumblue = 0.044077780212328,
mediumorchid = 0.21639251153773,
mediumpurple = 0.22905858091648,
mediumseagreen = 0.34393112338131,
mediumslateblue = 0.20284629471622,
mediumspringgreen = 0.70704308194184,
mediumturquoise = 0.5133827926448,
mediumvioletred = 0.14371899849357,
midnightblue = 0.02071786635086,
mintcream = 0.97834604947588,
mistyrose = 0.82183047859185,
moccasin = 0.80083000991567,
navajowhite = 0.76519682342785,
navy = 0.015585128108224,
oldlace = 0.91900633405549,
olive = 0.20027537200568,
olivedrab = 0.22593150951929,
orange = 0.4817026703631,
orangered = 0.25516243753416,
orchid = 0.31348806761439,
palegoldenrod = 0.78792647887614,
palegreen = 0.77936759006353,
paleturquoise = 0.76436077921714,
palevioletred = 0.28754994117889,
papayawhip = 0.87797100199835,
peachpuff = 0.74905589878251,
peru = 0.30113074877936,
pink = 0.63271070702466,
plum = 0.45734221587969,
powderblue = 0.68254586500605,
purple = 0.061477070432439,
rebeccapurple = 0.07492341159447,
red = 0.2126,
rosybrown = 0.32319457649407,
royalblue = 0.16663210743188,
saddlebrown = 0.097922285020521,
salmon = 0.36977241527596,
sandybrown = 0.46628543696283,
seagreen = 0.19734199706275,
seashell = 0.92737862206922,
sienna = 0.13697631337098,
silver = 0.52711512570581,
skyblue = 0.55291668518184,
slateblue = 0.14784278062136,
slategray = 0.20896704076536,
slategrey = 0.20896704076536,
snow = 0.96533341834849,
springgreen = 0.73052306068529,
steelblue = 0.20562642207625,
tan = 0.48237604163921,
teal = 0.16996855778968,
thistle = 0.56818401093733,
tomato = 0.30638612719415,
turquoise = 0.5895536427578,
violet = 0.40315452986676,
wheat = 0.74909702820482,
white = 1,
whitesmoke = 0.91309865179342,
yellow = 0.9278,
yellowgreen = 0.50762957208707,
}
6ae47fdb24de4eed5ec26d203faf5341a388987b
Шаблон:Население государства
10
100
210
2016-08-16T20:27:21Z
wikipedia, ruwikipedia>SandBot
0
/* top */удаление устаревшего ключа сортировки
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1}}}
| Республика Южная Осетия = Население Южной Осетии{{!}}Население
| Население
}}</includeonly><noinclude>
{{doc}}
[[Категория:Шаблоны по странам]]
</noinclude>
e0568280ef5056e94f5f1abf1934f4188a52c35f
Шаблон:Nobr
10
86
182
2016-12-02T13:15:38Z
wikipedia, ruwikipedia>Jack who built the house
0
используем класс nowrap
wikitext
text/x-wiki
<includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! -->
</noinclude>
989c6f164ed3a8543e916c8f1746ba1ab94fb068
Шаблон:Без уточнения
10
77
164
2017-03-12T19:54:44Z
wikipedia, ruwikipedia>Jack who built the house
0
бoлee кoppeктный пaттepн; нaпpимep, в «Haзвaниe (нeyтoчнeниe) (yтoчнeниe)» yтoчнeниeм дoлжнa cчитaтьcя тoлькo пocлeдняя чacть. вoзмoжнocть иcпол. бeз 1-гo пap. и пoдcтaн.
wikitext
text/x-wiki
<includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude>
1fcb3edb0be49656ae0f913e9a8fb4853264b480
Шаблон:Карточка/название
10
76
162
2017-08-01T19:26:37Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Шаблон:Карточка/название]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только адм…
wikitext
text/x-wiki
{{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude>
{{doc}}
</noinclude>
110edc6d8286f120a048863c68371720bd4e65ca
Модуль:Category handler/config
828
20
50
2017-08-01T19:26:42Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Модуль:Category handler/config]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Модуль:Category handler/blacklist
828
22
54
2017-08-01T19:26:43Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Модуль:Category handler/blacklist]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админис…
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template messages/.*$',
'/[aA]rchive' -- Don't categorise archives.
}
c84948ad9808d5d323408d5d10d5652f748a0550
Модуль:Category handler
828
16
42
2017-08-01T19:26:45Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Модуль:Category handler]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Модуль:Category handler/shared
828
21
52
2017-08-01T19:26:47Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Модуль:Category handler/shared]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист…
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Модуль:Category handler/data
828
19
48
2017-08-01T19:26:49Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Модуль:Category handler/data]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администр…
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Шаблон:Yesno
10
25
60
2017-08-01T19:30:50Z
wikipedia, ruwikipedia>Q-bit array
0
Защитил «[[Шаблон:Yesno]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бе…
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }}
|no
|n
|нет
|false
|0 = {{{no|<!-- null -->}}}
| = {{{blank|{{{no|<!-- null -->}}}}}}
|¬ = {{{¬|}}}
|yes
|y
|да
|true
|1 = {{{yes|yes}}}
|#default = {{{def|{{{yes|yes}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4e236854c477d07a225c2ab6c016c389b133e8d3
Шаблон:Langi
10
75
160
2017-10-14T07:25:47Z
wikipedia, ruwikipedia>Jack who built the house
0
→ [[/doc]]
wikitext
text/x-wiki
<span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude>
7bb9f9098c88e770b982402adf30a3bbf645aa4b
Шаблон:Lang-sv
10
99
208
2017-12-10T06:47:12Z
wikipedia, ruwikipedia>Dima st bk
0
langi
wikitext
text/x-wiki
[[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
c4b5e81c6405972dcea4cc26ab77e99e9bd2021f
Модуль:Arguments
828
10
30
2018-01-12T21:01:04Z
wikipedia, ruwikipedia>Grain of sand
0
sandbox → песочница
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/песочница$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
e6be8dfccffa2057c3d50700f350d8d140c1dbf9
Шаблон:Join
10
32
74
2018-06-13T14:41:38Z
wikipedia, ruwikipedia>Jack who built the house
0
перевод на модуль
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude>
{{doc}}
<!-- Категории — на подстраницу /doc, интервики — в Викиданные. -->
</noinclude>
92bb17b5322d3ae0ceab93d4dad3d31810d47eb0
Шаблон:Скрытый
10
62
134
2018-06-14T09:27:38Z
wikipedia, ruwikipedia>Iniquity
0
Iniquity переименовал страницу [[Шаблон:Скрытый]] в [[Шаблон:Скрытый блок]]: унификация названий, в схеме [[Википедия:Форум/Архив/Предложения/2018/01#Шаблоны,_скрывающие_содержимое]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Скрытый блок]]
97cc939c1c8ece875b2ec360f85980bd6f1bbed7
Шаблон:Конец скрытого блока
10
46
102
2018-06-14T09:55:59Z
wikipedia, ruwikipedia>Iniquity
0
общая документация
wikitext
text/x-wiki
<includeonly></div></div></includeonly><noinclude>
{{doc|Шаблон:Начало скрытого блока/doc}}</noinclude>
2da6ac8eb0812fb4183a70b516009d40920e281f
Шаблон:Без начала
10
96
202
2018-07-11T22:30:39Z
wikipedia, ruwikipedia>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude>
9fbca6f1fc236cb17fe77d76891e3f9c2afa2117
Шаблон:Str rightc
10
49
108
2018-07-11T22:33:58Z
wikipedia, ruwikipedia>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude>
0401d500dcc2224d44867ba0ea1f6c0fbeb758a0
Шаблон:Str left
10
31
72
2018-07-11T22:39:12Z
wikipedia, ruwikipedia>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude>
{{doc}}
</noinclude>
c1f57b63826f4d455dcaec8d2c24a2b8268f42ec
Шаблон:Str sub
10
42
94
2018-09-29T20:45:02Z
wikipedia, ruwikipedia>TenBaseT
0
категории в документации
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude>
{{doc}}
</noinclude>
3043790f8803e868cf6097b475fd58ba742887fe
Шаблон:No-doc
10
38
86
2019-01-17T08:39:04Z
wikipedia, ruwikipedia>Dima st bk
0
Защитил страницу [[Шаблон:No-doc]]: критический шаблон или модуль ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только администраторы] (бессрочно))
wikitext
text/x-wiki
{{#ifeq: {{SUBPAGENAME}} | doc
|| {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }}
|| {{{1|}}}
}}
}}<noinclude>{{doc}}</noinclude>
da013ca5b5f97f94bee392ff3a4488046f2ceac7
Шаблон:Demo
10
102
214
2019-04-25T13:40:59Z
wikipedia, ruwikipedia>QBA-bot
0
Защитил страницу [[Шаблон:Demo]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude>
e458e378477c6077a01987f334fdc73bee48512c
Модуль:Wikidata/count
828
95
200
2019-06-29T03:57:18Z
wikipedia, ruwikipedia>Dima st bk
0
Изменил уровень защиты [[Модуль:Wikidata/count]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
Scribunto
text/plain
local p = {}
function p.getCount( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims;
if options.property then -- TODO: Почему тут может не быть property?
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return ''; --TODO error?
end
return table.getn(claims);
end
function p.isMultiple( context, options )
local count = p.getCount( context, options );
local multiple = '';
if( count ~= nil and count ~= '' and count > 1 ) then
multiple = 1;
end
return multiple;
end
return p
8ccf5dd7170a466674627b0afdf32c6bd2318154
Модуль:TableTools
828
11
32
2019-08-26T06:20:31Z
wikipedia, ruwikipedia>Serhio Magpie
0
Обновлено с https://en.wikipedia.org/w/index.php?title=Module:TableTools&oldid=887403551
Scribunto
text/plain
--[[
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should --
-- not be called directly from #invoke. --
------------------------------------------------------------------------------------
--]]
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
checkType('removeDuplicates', 1, t, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will
-- return {1, 3, 6}.
------------------------------------------------------------------------------------
--]]
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
return s
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k, v in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table
-- of subtables in the format
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }
-- Keys that don't end with an integer are stored in a subtable named "other".
-- The compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
--]]
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for k in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
else -- This will fail with table, boolean, function.
return item1 < item2
end
end
--[[
Returns a list of the keys in a table, sorted using either a default
comparison function or a custom keySort function.
]]
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })
end
local list = {}
local index = 1
for key, value in pairs(t) do
list[index] = key
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(list, keySort)
end
return list
end
--[[
Iterates through a table, with the keys sorted using the keysToList function.
If there are only numerical keys, sparseIpairs is probably more efficient.
]]
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local list = p.keysToList(t, keySort, true)
local i = 0
return function()
i = i + 1
local key = list[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
--[[
Returns true if all keys in the table are consecutive integers starting at 1.
--]]
function p.isArray(t)
checkType("isArray", 1, t, "table")
local i = 0
for k, v in pairs(t) do
i = i + 1
if t[i] == nil then
return false
end
end
return true
end
-- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 }
function p.invert(array)
checkType("invert", 1, array, "table")
local map = {}
for i, v in ipairs(array) do
map[v] = i
end
return map
end
--[[
{ "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true }
--]]
function p.listToSet(t)
checkType("listToSet", 1, t, "table")
local set = {}
for _, item in ipairs(t) do
set[item] = true
end
return set
end
--[[
Recursive deep copy function.
Preserves identities of subtables.
]]
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = deepcopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
--[[
Concatenates all values in the table that are indexed by a number, in order.
sparseConcat{ a, nil, c, d } => "acd"
sparseConcat{ nil, b, c, d } => "bcd"
]]
function p.sparseConcat(t, sep, i, j)
local list = {}
local list_i = 0
for _, v in p.sparseIpairs(t) do
list_i = list_i + 1
list[list_i] = v
end
return table.concat(list, sep, i, j)
end
--[[
-- This returns the length of a table, or the first integer key n counting from
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return
-- a different value when there are gaps in the array portion of the table.
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of
-- the number of unnamed template parameters, so use this function for
-- frame.args.
--]]
function p.length(t)
local i = 1
while t[i] ~= nil do
i = i + 1
end
return i - 1
end
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
fe918509f168332267834b3a6f5c219a9de5b2e7
Шаблон:Br separated entries
10
90
190
2019-08-30T23:08:35Z
wikipedia, ruwikipedia>Ле Лой
0
Защитил страницу [[Шаблон:Br separated entries]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude>
{{doc}}
</noinclude>
2113c3c6e95a84235b9f7a85e7ea17208e8f91df
Шаблон:T
10
40
90
2019-10-20T16:35:32Z
wikipedia, ruwikipedia>Helgo13
0
Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tl]]
c0a76efe437d8a513d9f6878297f399a23944abd
Шаблон:Tl
10
41
92
2019-10-20T16:35:32Z
wikipedia, ruwikipedia>Helgo13
0
Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]]
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude>
61fe4d068895a5e7e5802767f5d7df71a7561c57
Шаблон:Карточка/внизу
10
26
62
2019-11-13T23:18:52Z
wikipedia, ruwikipedia>Serhio Magpie
0
Перенесено в общие стили
wikitext
text/x-wiki
<includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude>
{{doc}}
</noinclude>
169fb2d10b0847c2fd677eda9f159ba99025198f
Шаблон:If-wikidata
10
87
184
2019-11-13T23:40:02Z
wikipedia, ruwikipedia>Serhio Magpie
0
+ from
wikitext
text/x-wiki
{{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude>
{{doc}}
</noinclude>
a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb
Шаблон:Карточка/официальное название
10
97
204
2020-02-29T12:06:43Z
wikipedia, ruwikipedia>Helgo13
0
Защитил страницу [[Шаблон:Карточка/официальное название]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
wikitext
text/x-wiki
{{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude>
708a700c58a199343531d8fb3eec7ee897e92732
Модуль:Separated entries
828
39
88
2020-07-05T06:33:20Z
wikipedia, ruwikipedia>Serhio Magpie
0
+ newline
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux".
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.newline = makeInvokeFunction('\n')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
33a68f0a46d62c42b6523a548f0f881e82ecfe58
Шаблон:Wikidata number switch
10
79
168
2020-07-12T09:21:12Z
wikipedia, ruwikipedia>Serhio Magpie
0
Проверка - если ничего нет из первых трёх параметров, ничего и не выводить
wikitext
text/x-wiki
{{#if: {{{3|}}}
| {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }}
| {{#if: {{{2|}}}
| {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }}
| {{#if: {{{1|}}}
| {{#if: {{{4|}}}{{{5|}}}
| {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }}
| {{wikidata|{{{1|}}}|from={{{from|}}}}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
7541bb47e73905a8ee240baa1dab1801f9f7b166
Шаблон:Карточка/блок
10
92
194
2020-10-20T13:56:13Z
wikipedia, ruwikipedia>Wikisaurus
0
Wikisaurus переименовал страницу [[Шаблон:Фрагмент таблицы]] в [[Шаблон:Карточка/блок]]: унификация с другими шаблонами для создания частей карточки
wikitext
text/x-wiki
<includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude>
b76f4bc95a8a44fea1fa0f577d84111b51ce1385
Модуль:Transclude
828
29
68
2020-11-17T12:38:34Z
wikipedia, ruwikipedia>Wikisaurus
0
пропускать пустые параметры в forall и join
Scribunto
text/plain
local p={}
-- Вызывает внутренний шаблон с аргументами объемлющего шаблона
function p.call(frame)
local template = frame.args[1]
local args = frame:getParent().args
return frame:expandTemplate{ title=template, args=args }
end
-- Общая реализация для forall и call
local function forallImpl(args, separator, conjunction, func)
-- нумерованные ключи из args
local keys = {}
-- перебор в произвольном порядке, даже для нумерованных ключей
for key, value in pairs(args) do
if type(key) == 'number' and value and value ~= '' then
table.insert(keys, key)
end
end
table.sort(keys)
local results = {}
for _, key in ipairs(keys) do
local value = func(args[key])
table.insert(results, value)
end
return mw.text.listToText(results, separator, conjunction)
end
-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному
function p.forall(frame)
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local args = frame:getParent().args
local func = function(value)
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame?
end
return forallImpl(args, separator, conjunction, func)
end
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку
function p.join(frame)
local separator = frame.args[1] or ''
local conjunction = frame.args[2] or separator
local args = frame:getParent().args
local func = function(value)
return value
end
return forallImpl(args, separator, conjunction, func)
end
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами
local function deleteDuplicates(args)
local res = {}
for key, value in pairs(args) do
if args[key+1] ~= value then
table.insert(res, value)
end
end
return res
end
-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона
function p.npc(frame)
local args = frame:getParent().args
local templateFrame = frame:getParent()
local template = frame.args[1]
-- определение, блоки аргументов с какими номерами нужны:
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок
local nums = {}
for key, _ in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- учитывать "параметр12", только если задано "параметр"
if num and frame.args[main] then
table.insert(nums, num)
end
end
table.sort(nums)
nums = deleteDuplicates(nums)
-- проходить по нужным номерам блоков по возрастанию и однократно
-- подставлять в шаблон:
-- 1. общие аргументы данного модуля
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок
local results = {}
for _, blockNum in ipairs(nums) do
-- общие аргументы модуля, которые передаются в каждый блок
local blockArgs = mw.clone(frame.args)
-- metatable ломает expandTemplate
setmetatable(blockArgs, nil)
for key, value in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля
if blockNum == num and frame.args[main] then
blockArgs[main] = value
end
end
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs }
table.insert(results, blockText)
end
return table.concat(results)
end
-- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2].
function p.cycle(f)
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline';
local sep='';
if op == 'newline' then
sep='\n';
end
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
s=tonumber(s);
local acr={};
if not s then error('Начало цикла «'..s..'» — не число') end
local function dc(order)
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
if order == 'desc' then
s=s-1;
else
s=s+1;
end
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
if fh > s then
while s<=fh do dc('asc') end
else
while s>=fh do dc('desc') end
end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
else
while dc('asc') do end
end
return table.concat(acr, sep)
end
return p
c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59
Модуль:Hash
828
50
110
2021-02-07T10:01:11Z
wikipedia, ruwikipedia>Grain of sand
0
+ list() для вывода списка доступных алгоритмов
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function inTable(table, value)
for k, v in pairs(table) do
if v == value then
return true
end
end
return false
end
function p.list(frame)
return table.concat(mw.hash.listAlgorithms(), '; ')
end
function p.main(frame)
local args = getArgs(frame, { frameOnly = true })
local algorithm
if not args[1] then
return '<span class="error">Не указана строка для хеширования.</span>'
end
if args[2] then
if not inTable(mw.hash.listAlgorithms(), args[2]) then
return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>'
end
algorithm = args[2]
else
-- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]),
-- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой
-- величины. Возможно, есть лучшая опция — проверяйте.
algorithm = 'fnv164'
end
return mw.hash.hashValue(algorithm, args[1])
end
return p
5d18513e574435f191164695449a620b031f93ec
Шаблон:Doc/end
10
58
126
2021-02-14T18:18:13Z
wikipedia, ruwikipedia>Putnik
0
для модулей предзагрузка нормально не работает
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Модуль:Песочница|песочнице для модулей]]
| своём [[ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}</noinclude>
758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e
Шаблон:Tnav
10
65
140
2021-02-28T17:42:07Z
wikipedia, ruwikipedia>Jack who built the house
0
дополнение
wikitext
text/x-wiki
{{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude>
{{doc-inline}}
Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}.
{{шаблоны для документирования}}
{{doc-end}}
[[Категория:Шаблоны:Ссылки на шаблоны]]
[[Категория:Шаблоны:Для навигационных шаблонов]]
</noinclude>
583d607aa213790ae32dda4018a413255493e42b
Модуль:Color contrast
828
34
78
2021-03-01T22:40:23Z
wikipedia, ruwikipedia>Grain of sand
0
local
Scribunto
text/plain
--
-- This module implements
-- {{Color contrast ratio}}
-- {{Greater color contrast ratio}}
-- {{ColorToLum}}
-- {{RGBColorToLum}}
--
local p = {}
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )
local function sRGB ( v )
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function rgbdec2lum( R, G, B )
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
return ''
end
end
local function hsl2lum( h, s, l )
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
local c = (1 - math.abs(2*l - 1))*s
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
local m = l - c/2
local r, g, b = m, m, m
if( 0 <= h and h < 60 ) then
r = r + c
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
local function color2lum( c )
if (c == nil) then
return ''
end
-- whitespace
c = c:match( '^%s*(.-)[%s;]*$' )
-- lowercase
c = c:lower()
-- first try to look it up
local L = HTMLcolor[c]
if (L ~= nil) then
return L
end
-- convert from hsl
if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
end
-- convert from rgb
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
-- convert from rgb percent
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
end
-- remove leading # (if there is one) and whitespace
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
return rgbdec2lum(R, G, B)
end
-- failure, return blank
return ''
end
function p._greatercontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
local v1 = color2lum(args[1] or '')
local c2 = args[2] or '#FFFFFF'
local v2 = color2lum(c2)
local c3 = args[3] or '#000000'
local v3 = color2lum(c3)
local ratio1 = 0;
local ratio2 = 0;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end
return (ratio1 + bias > ratio2) and c2 or c3
end
function p._ratio(args)
local v1 = color2lum(mw.text.unstripNoWiki(args[1] or ''))
local v2 = color2lum(mw.text.unstripNoWiki(args[2] or ''))
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end
function p._styleratio(args)
local style = (args[1] or ''):lower()
local bg, fg = 'white', '#202122'
local lum_bg, lum_fg = 1, 0.016
if args[2] then
local lum = color2lum(args[2])
if lum ~= '' then bg, lum_bg = args[2], lum end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then fg, lum_fg = args[3], lum end
end
local slist = mw.text.split(style or '', ';')
for k = 1, #slist do
local s = slist[k]
local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
k = k or ''
v = v or ''
if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_bg = v, lum end
elseif (k:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_fg = v, lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
function p.lum(frame)
return color2lum(frame.args[1] or frame:getParent().args[1])
end
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
end
function p.styleratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._styleratio(args)
end
function p.greatercontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._greatercontrast(args)
end
return p
cce580326bee8eaf3c81df6c76c04a9a2909dfa2
Шаблон:Wikidata
10
78
166
2021-04-01T12:24:50Z
wikipedia, ruwikipedia>MBH
0
[[ВП:Откат|откат]] правок [[Special:Contribs/Lê Lợi (bot)|Lê Lợi (bot)]] ([[UT:Lê Lợi (bot)|обс.]]) к версии Wikisaurus
wikitext
text/x-wiki
<includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude>
9d3d422eca39504b018df6ec0bb047392a7aba7e
Модуль:Infobox
828
28
66
2021-08-16T20:12:46Z
wikipedia, ruwikipedia>Putnik
0
scope="colgroup" для заголовков
Scribunto
text/plain
local p = {};
local yesno = require('Module:Yesno')
local function _renderLine( frame, args, i )
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then
return ''
elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' );
local class = ( args[ 'класс' .. i ] or '' );
return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' ..
args[ 'заголовок' .. i ] ..
'</th>\n</tr>';
end
if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then
return args[ 'блок' .. i ];
end
local text = args[ 'текст' .. i ] or '';
if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then
text = frame:expandTemplate{ title = 'Wikidata', args = {
args[ 'викиданные' .. i ],
text,
from = args[ 'from' ] or ''
} };
end
if text ~= '' then
local label = args[ 'метка' .. i ] or '';
local class = args[ 'класс' .. i ] or '';
if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then
class = class .. ' plainlist';
end
if class ~= '' then
class = ' class="' .. class .. '"';
end
local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' );
if label == '' then
style = 'text-align:center;' .. style;
end
if style ~= '' then
style = ' style="' .. style .. '"';
end
if label ~= '' then
local labelClass = args[ 'класс_меток' ] or '';
if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then
labelClass = labelClass .. ' plainlist';
end
if labelClass ~= '' then
labelClass = ' class="' .. labelClass .. '"';
end
local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' );
if labelStyle ~= '' then
labelStyle = ' style="' .. labelStyle .. '"';
end
return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' ..
'\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '';
end
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.renderLine( frame )
local args = frame:getParent().args;
return _renderLine(frame, args, '')
end
function p.renderLines( frame )
local args = frame:getParent().args;
local res = ''
local header, text = '', ''
local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false)
for i = 1, maxNumber(args) do
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
header, text = _renderLine(frame, args, i), ''
else
text = text .. _renderLine(frame, args, i)
end
end
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
return res
end
return p;
c830c997bd3d15923f347277e3b0ae71b7ba917e
Шаблон:Карточка/блок с маркерами
10
91
192
2021-10-24T15:48:39Z
wikipedia, ruwikipedia>Oleg Yunakov
0
Защитил страницу [[Шаблон:Карточка/блок с маркерами]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude>
71e7755aa4fb1e445f008da13d6fa4212aea3c38
Шаблон:Ombox
10
59
128
2021-10-24T18:05:30Z
wikipedia, ruwikipedia>Oleg Yunakov
0
Изменил настройки защиты для «[[Шаблон:Ombox]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
ab34435c5ebc29de589c9b059e88da5d0e6f16e4
Модуль:Infobox/bulleted block
828
93
196
2021-10-24T18:17:22Z
wikipedia, ruwikipedia>Oleg Yunakov
0
Защитил страницу [[Модуль:Infobox/bulleted block]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
Scribunto
text/plain
local p = {}
-- takes strings or nils; returns a string
function makeText(frame, text, wikidata, from)
if wikidata and wikidata ~= ''then
return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}}
else
return text or ''
end
end
-- from [[ru:Модуль:Infobox]]
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.main(frame)
local args = frame:getParent().args
local maxNumberArgs = maxNumber(args)
local texts = {}
for i = 1, maxNumberArgs do
if args['текст' .. i] then
texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from'])
end
end
local textsAreEmpty = true
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
textsAreEmpty = false
end
end
local results = {}
if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then
results['текст1'] = args['подзаголовок']
results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;'
end
local mainText = makeText(frame, args['текст'], args['викиданные'], args['from'])
if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then
mainText = ' '
end
if mainText and mainText ~= '' then
results['метка2'] = args['метка']
results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;'
results['текст2'] = mainText
results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;'
end
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
results['метка' .. (i+2)] = ' • ' .. (args['метка' .. i] or '')
results['текст' .. (i+2)] = texts[i]
local last = true
for j = i+1, maxNumberArgs do
if texts[j] and texts[j] ~= '' then
last = false
end
end
if last then
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;'
else
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
end
end
end
return frame:expandTemplate{title='Карточка/блок', args=results}
end
return p
856b97606e1f2809c940e384f6fe71a575ca019e
Шаблон:Tlp
10
52
114
2021-10-24T18:18:30Z
wikipedia, ruwikipedia>Oleg Yunakov
0
Изменил настройки защиты для «[[Шаблон:Tlp]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude>
36c309cb28ccf0901f4fff46cbd35cdabcf00661
Модуль:Template call code
828
12
34
2021-10-26T19:03:06Z
wikipedia, ruwikipedia>Jack who built the house
0
-избыточный код
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName, flags)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args, flags)
end
end
--предотвращает обработку вики-текста в отображении образца
local function processText(str, nowiki)
local res = str
if nowiki then
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
end
return str
end
local function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
local function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
text = text .. ' ts-templateCallCode-weak'
end
-- |, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">|</span>'
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
if k >= params.from then
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
else -- Истинно неименованные
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
end
end
return text
end
function p._main(args, flags)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if not flags.withoutParams then
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
end
local yesno = require('Module:Yesno')
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr
local tag, style, comment, lang, sister, global, textInPlaceOfName,
namePrefix, prefix, postfix, nowiki
local spaced, from
if flags.withoutParams then
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
noLink = true
elseif v == 's' then
subst = true
elseif v == 'п' then
podst = true
elseif v == 'g' then
global = true
elseif v == 'nav' then
nav = true
elseif v == 'noredir' then
noRedirect = true
elseif v == 'u' then
ucFirst = true
elseif v == 'b' then
black = true
elseif v == 'nobr' then
nobr = true
end
end
tag = args.tag or 'span'
style = args.style
comment = args.comment
lang = args.lang
sister = args.sister
textInPlaceOfName = args.text
namePrefix = args.nameprefix
prefix = args.prefix
postfix = args.postfix
nowiki = args.nowiki
else
noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
subst = yesno(args._s, false)
podst = yesno(args['_п'], false)
global = yesno(args._g, false)
nav = yesno(args._nav, false)
noRedirect = yesno(args._noredir, false)
ucFirst = yesno(args._u, false)
black = yesno(args._b, false)
nobr = yesno(args._nobr, false)
tag = args._tag or 'span'
style = args._style
comment = args._comment
lang = args._lang
sister = args._sister
textInPlaceOfName = args._text
namePrefix = args._nameprefix
prefix = args._prefix
postfix = args._postfix
nowiki = args._nowiki
spaced = yesno(args._spaced, false)
from = (tonumber(args._from) or 2) - 1
end
global = global or name and mw.ustring.sub(name, 1, 1) == ':'
black = black or tag ~= 'span'
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if namePrefix == '' then
namePrefix = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if subst then
namePrefix = 'subst:'
elseif podst then
namePrefix = 'подст:'
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
(
(
ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="ts-templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. processText(prefix, nowiki)
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">{{'
if namePrefix then
text = text .. namePrefix
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">'
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.withoutParams then
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
nowiki = nowiki,
from = from
})
if spaced then
text = text .. ' '
end
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">}}</span>'
if postfix then
text = text .. processText(postfix, nowiki)
end
if tag then
text = text .. '</' .. tag .. '>'
end
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
function p._onlyParams(args)
local yesno = require('Module:Yesno')
return addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
nowiki = yesno(args._nowiki, false),
from = 1
})
end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')
return p
c4cde66869b509219e9bf629a766ce30ad0bdf97
Шаблон:Ifempty
10
45
100
2021-11-07T14:03:01Z
wikipedia, ruwikipedia>Grain of sand
0
на модуль
wikitext
text/x-wiki
<includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude>
{{Doc}}
<!-- Add categories and interwikis to the /doc subpage, not here!
Добавляйте категории и интервики на подстраницу документации, а не сюда -->
</noinclude>
c14bef2160201468f96da309e565ff2fde725cf5
Модуль:Ifempty
828
48
106
2021-11-08T15:29:31Z
wikipedia, ruwikipedia>Ping08
0
Изменил настройки защиты для «[[Модуль:Ifempty]]»: критический шаблон или модуль: более 125000 включений ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
Scribunto
text/plain
local p = {}
local getArgs = require('Module:Arguments').getArgs
function p.main(frame)
local args = getArgs(frame, {removeBlanks = false})
local before = args['до']
local after = args['после']
for i, v in ipairs(args) do
if v ~= '' then
return (before or '') .. v .. (after or '')
end
end
end
return p
875e8c9f03fb4cc02d80271ad3aaab13a9bcea86
Модуль:Template call code/styles.css
828
14
38
2021-11-15T10:35:51Z
wikipedia, ruwikipedia>Jack who built the house
0
поддержка [[t:optp]] (например, на [[Модуль:Unsubst/doc]])
text
text/plain
.ts-templateCallCode-weak {
color: #72777d;
}
.ts-templateCallCode-pipe {
margin: 0 2px;
}
.ts-templateCallCode-pipe + .ts-templateCallCode-pipe,
/* Template:Optp */
.ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child {
margin-left: 0;
}
.ts-templateCallCode-param + .ts-templateCallCode-closing {
margin-left: 2px;
}
span.ts-templateCallCode > .ts-templateCallCode-templateName a {
/* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */
padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */
position: relative;
margin: -0.5em;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b3ed166240cf28c48a58b8d992794b753b2c6ef5
Шаблон:Карточка
10
8
26
2022-04-03T23:49:38Z
wikipedia, ruwikipedia>Putnik
0
пробуем красить каждую карточку на странице отдельно, без перекрытия стилей; надеюсь, комбинация имя+вверху0+вверху+вверху2 достаточно уникальна и не вызовет ошибок
wikitext
text/x-wiki
{{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles|
|wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}}
|src=Шаблон:Цвет/{{{цвет|}}}.css
}}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!--
-->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!--
-->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Википедия:Шаблоны-карточки с явным указанием стилей]]}}<!--
-->}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Википедия:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Википедия:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}</noinclude>
5bd0cadc0cad51dc109de7db63622ab36743d386
Шаблон:Карточка/Викисклад
10
80
170
2022-04-30T14:39:04Z
wikipedia, ruwikipedia>ShinePhantom
0
еще одна проверочная категория для зачистки
wikitext
text/x-wiki
{{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!--
-->{{#if: {{wikidata|p373|plain=true}}
| {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }}
| [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]]
}} }}<!--
--> }}<!--
-->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!--
--><noinclude>
{{doc}}
</noinclude>
40ef9a463c772ddbf54feae9e21d4037b692253e
Модуль:WikidataSelectors
828
84
178
2023-05-09T18:46:16Z
wikipedia, ruwikipedia>Putnik
0
исправление метода load()
Scribunto
text/plain
local i18n = {
["errors"] = {
["rank-not-valid"] = "Некорретное значение приоритета (rank)",
["cant-parse-condition"] = "Не удалось разобрать условие"
}
}
local validRanks = {
'best',
'preferred',
'normal',
'deprecated'
}
--[[
Internal function for error message
Input: key in errors table
Output: error message
]]
local function throwError( key )
error( i18n.errors[key] )
end
local p = {}
--[[
Load property and filter statements
Input: entityId, selector string
Output: filtered statements table
]]
function p.load( entityId, propertySelector )
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
return nil
end
propertyId = string.upper( propertyId )
local allStatements = {}
allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
return p.filter( allStatements, propertySelector )
end
--[[
Parse selectors and filter statements
Input: statements table, selector string
Output: filtered statements table
]]
function p.filter( allClaims, propertySelector )
propertySelector = mw.text.trim( propertySelector )
-- Get property ID from selector
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
propertyId = ''
end
local initPos = #propertyId + 1
propertyId = string.upper( propertyId )
if ( not allClaims ) then
return nil
end
local allPropertyClaims = allClaims[propertyId]
if ( not allPropertyClaims ) then
return nil
end
-- Gathering rules
local rules = p.matchSelectors( propertySelector, initPos )
-- If there is no rank filter, than default rank is 'best'
local isRanked = false
for i, subRules in ipairs( rules ) do
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
isRanked = true
break
end
end
end
if not isRanked then
table.insert( rules, 1, { { type = 'rank', value = 'best' } } )
end
-- Execute rules
allPropertyClaims = p.applyRules( allPropertyClaims, rules )
return allPropertyClaims
end
--[[
Match and gather selector rules
Input: string with selectors rules, start position
Output: rules table
]]
function p.matchSelectors( selectorsString, initPos )
local rules = {}
local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*'
local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$'
if not initPos then
initPos = 1
end
local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
while rawRule do
initPos = initPos + #rawRule
rule = mw.ustring.match( rawRule, rulePattern )
rule = mw.text.trim( rule )
local subRules = mw.text.split( rule, '%s*,%s*' )
local commands = {}
local comm
for i, subRule in ipairs( subRules ) do
local isInversed = false
if mw.ustring.match( subRule, '^!' ) then
isInversed = true
subRule = mw.ustring.match( subRule, '^!%s*(.+)$' )
end
-- p123[1]
if mw.ustring.match( subRule, '^%d+$' ) then
table.insert( commands, {
type = 'position',
value = subRule,
inversed = isInversed
} )
-- p123[rank:preferred]
elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then
rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' )
table.insert( commands, {
type = 'rank',
value = rank,
inversed = isInversed
} )
-- p123[language:xx]
elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = isInversed
} )
-- p123[language!:xx]
elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = not isInversed
} )
-- p123[min]
elseif mw.ustring.match( subRule, '^min$' ) then
table.insert( commands, { type = 'value_min' } )
-- p123[max]
elseif mw.ustring.match( subRule, '^max$' ) then
table.insert( commands, { type = 'value_max' } )
-- p123[min:p456]
elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_min',
qualifier = value
} )
-- p123[max:p456]
elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_max',
qualifier = value
} )
-- p123[unit:q789]
elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = isInversed
} )
-- p123[unit!:q789]
elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = not isInversed
} )
-- p123[p456]
elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then
qualifier = mw.ustring.match( subRule, '^[Pp]%d+' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = nil,
inversed = isInversed
} )
-- p123[p456:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' )
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = isInversed
} )
-- p123[p456!:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' )
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = not isInversed
} )
-- p123[q456]
elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then
value = mw.ustring.match( subRule, '^[Qq]%d+' )
table.insert( commands, {
type = 'value',
value = value,
inversed = isInversed
} )
else
throwError( 'cant-parse-condition' )
end
end
if #commands then
table.insert( rules, commands )
end
rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
end
return rules
end
--[[
Intercept statements with selector rules
Input: statements table, selector rules
Output: filtered statements table
]]
function p.applyRules( claims, rules )
for i, subRules in ipairs( rules ) do
local newClaims = {}
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'language' then
table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'unit' then
table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'position' then
table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier' then
table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier_min' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) )
elseif rule['type'] == 'qualifier_max' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) )
elseif rule['type'] == 'value' then
table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'value_min' then
table.insert( newClaims, p.filterUtter( claims, true ) )
elseif rule['type'] == 'value_max' then
table.insert( newClaims, p.filterUtter( claims, false ) )
end
end
claims = {}
--[[
Merge all claims
TODO: It's not good
]]
for j, newSubClaims in ipairs( newClaims ) do
for k, newClaim in ipairs( newSubClaims ) do
local isNew = true
for l, oldClaim in ipairs( claims ) do
if oldClaim['id'] == newClaim['id'] then
isNew = false
break
end
end
if isNew then
table.insert( claims, newClaim )
end
end
end
end
return claims
end
--[[
Filter statements by rank
Input: claims table, rank value, inversion
Output: filtered statements table
]]
function p.filterByRank( claims, rank, inversed )
if not inversed then
inversed = false
end
if not rank then
rank = 'best'
end
-- Check if rank value is valid
local isValidRank = false
for i, validRank in ipairs( validRanks ) do
if rank == validRank then
isValidRank = true
break
end
end
if not isValidRank then
throwError( 'rank-not-valid' )
end
-- Find the best rank
if rank == 'best' then
rank = 'normal' -- default rank (don't use deprecated even if it's no more claims)
-- If we have at least one preferred rank, mark it as best
for i, statement in pairs( claims ) do
if (statement.rank == 'preferred') then
rank = 'preferred'
break
end
end
end
local resultClaims = {};
for i, statement in pairs( claims ) do
if ( statement.rank == rank ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by language of value
Input: claims table, language, inversion
Output: filtered statements table
]]
function p.filterByLanguage( claims, language, inversed )
if not inversed then
inversed = false
end
local resultClaims = {}
local mulStatement = {}
for i, statement in ipairs( claims ) do
isMatchLanguage = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['language'] then
if statement['mainsnak']['datavalue']['value']['language'] == language then
isMatchLanguage = true
end
if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then
mulStatement = statement
end
end
if isMatchLanguage ~= inversed then
table.insert( resultClaims, statement )
end
end
if next(resultClaims) == nil and next(mulStatement) ~= nil then
-- if specific language is not found, but there is Q20923490 value
table.insert( resultClaims, mulStatement )
end
return resultClaims
end
--[[
Filter statements by unit of value
Input: claims table, unit, inversion
Output: filtered statements table
]]
function p.filterByUnit( claims, unit, inversed )
if not inversed then
inversed = false
end
unit = 'http://www.wikidata.org/entity/' .. string.upper( unit )
local resultClaims = {}
for i, statement in ipairs( claims ) do
isMatchUnit = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['unit']
and statement['mainsnak']['datavalue']['value']['unit'] == unit then
isMatchUnit = true
end
if isMatchUnit ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by position
Input: claims table, position, inversion
Output: filtered statements table
]]
function p.filterByPosition( claims, position, inversed )
if not inversed then
inversed = false
end
local resultClaims = {};
for statementPosition, statement in ipairs( claims ) do
if ( statementPosition == tonumber( position ) ) ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by qualifier existance or it's value
Input: claims table, ID of qualifier's property, qualifier's value, inversion
Output: filtered statements table
]]
function p.filterByQualifier( claims, qualifierId, value, inversed )
if not inversed then
inversed = false
end
qualifierId = string.upper( qualifierId )
local resultClaims = {}
for i, statement in ipairs( claims ) do
if statement['qualifiers'] and statement['qualifiers'][qualifierId] then
if value == nil then
if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then
table.insert( resultClaims, statement )
end
else
local isQualifierFound = false
for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
value = string.upper( value )
end
if qualifierValue == value then
isQualifierFound = true
break
end
end
end
if isQualifierFound ~= inversed then
table.insert( resultClaims, statement )
end
end
elseif inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by it's values
Input: claims table, value, inversed
Output: filtered statements table
]]
function p.filterByValue( claims, value, inversed )
inversed = inversed or false
local resultClaims = {}
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
value = string.upper( value )
end
end
if ( statementValue == value ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Find a statement with minimum or maximum value
Input: claims table, asc, inversed
Output: filtered statements table
]]
function p.filterUtter( claims, asc, inversed )
local resultValue = nil
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak'] and
statement['mainsnak']['datavalue'] and
statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
end
if not resultValue or ( statementValue < resultValue ) == asc then
resultValue = statementValue
end
end
end
mw.logObject( resultValue, 'resultValue' )
return p.filterByValue( claims, resultValue, inversed )
end
--[[
Find a statement with minimum or maximum qualifier value
Input: claims table, qualifierId, asc
Output: filtered statements table
]]
function p.filterUtterByQualifier( claims, qualifierId, asc )
qualifierId = string.upper( qualifierId )
local resultValue = nil
local resultStatement = nil
for i, statement in ipairs( claims ) do
if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then
if resultStatement == nil then
resultStatement = statement
end
else
for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'quantity' then
qualifierValue = qualifierValue.amount
end
if qualifier['datavalue']['type'] == 'time' then
qualifierValue = qualifierValue.time
end
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
end
if not resultValue or ( qualifierValue < resultValue ) == asc then
resultStatement = statement
resultValue = qualifierValue
end
end
end
end
end
return { resultStatement }
end
return p
0bdff3a63bf171160cdec5c966211fbbf3003880
Модуль:Calendar
828
17
44
2023-05-17T17:44:45Z
wikipedia, ruwikipedia>Dima st bk
0
+ короткие варианты для английского, см. [[Обсуждение шаблона:Cite web#Формат параметра %7Carchive-date=]]
Scribunto
text/plain
local p = {}
-- Необходимые модули и переменные
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local mwlang = mw.getContentLanguage()
local err = "―" -- NthDay nil result
local tCon = table.concat
-- 00) Блок многократно используемых списков
local bool_to_number={ [true]=1, [false]=0 }
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"}}
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
-- duplicates:
-- AST, BST, CST, ECT, IST, MST, PST, SST,
local known_tzs = {
ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00',
AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00',
AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00',
BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00',
BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30',
CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45',
CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00',
COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00',
CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00',
ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00',
EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00',
GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00',
GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00',
HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30',
IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00',
LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30',
MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30',
MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30',
NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00',
SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00',
SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00',
UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00',
WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00',
-- US Millitary (for RFC-822)
Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
}
local category = {
["no_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->",
["incomplete_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->",
["without_verification"]=
"<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->",
["erroneous_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->"
}
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением
local e = {
["start"]="<span class=error>Ошибка: ",
["ending"]=".</span>",
["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами",
["no_valid_date"]="дата «%s» не является корректной",
["wrong_jd"]="юлианская дата %s вне диапазона",
["no_data"]="нет входящих данных",
["too_many_arguments"]="ожидается менее %i аргументов",
["too_little_arguments"]="ожидается более %i аргументов",
["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница",
["unknown_param"]="параметр %s неизвестен",
["unknown_error"]="неизвестная ошибка",
["tech_error"]="ошибка в функции %s",
["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД"
-- [""]="",
}
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
local pattern = { -- для распознавания дат, переданных одним строчным параметром
{"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd
{"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy
{"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy
{"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm
{"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y
{"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y
{"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y
}
local time_units = {"year","month","day"} --не используется
--[[ local time_units = {"second", "minute", "hour",
"day_of_month", "day_of_week", "day_of_year",
"week", "month", "year", "year_of_century", "century"} ]]--
-- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов
local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"}
local month_lang = {
["ru_G"] = {"января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря"},
["ru_N"] = {"январь","февраль","март","апрель","май","июнь",
"июль","август","сентябрь","октябрь","ноябрь","декабрь"},
["en"] = {"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"},
["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"},
["de"] = {"januar", "februar", "märz", "april", "mai", "juni",
"juli", "august", "september", "oktober", "november", "dezember"},
["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"}
}
-- заполняется автоматически
local reverse_month_lang = {}
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)
local reverse_table = function (strait_table)
local reversed_table = {}
for k,v in pairs(strait_table) do
reversed_table[v] = k
end
return reversed_table
end
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат
local filling_months = function (mnlang, month_lang)
for i=1, #mnlang do
reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]])
end
end
-- 10) Блок общих функций
local function trim(str)
if not str then return nil
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
end
local function purif(str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter?
end
local function is(str)
if (not str) or (str == "") then return false
else return yesno(str,false)
end
end
local function init(num)
local output = {}
for i=1,num do
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
end
return unpack(output)
end
local function isyear(tbl)
if type(tbl) ~= 'table' then return false
elseif not tbl["year"] then return false
elseif type(tbl["year"]) == 'number' then return true
else return false
end
end
local function inbord(val, down, up)
return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)
end
local function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local inlist = function ( var, list )
local n = #list
local inlist = false
for i=1,n do
if var == list[i] then inlist = true end
end
return inlist
end
-- 20) Блок общих проверочных функций, связанных с датами
local function unwarp(tbl)
if not tbl then return ""
elseif type(tbl) ~= "table" then return tbl
elseif (tbl.day or tbl.month or tbl.year) then
return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?")
else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?")
end
end
local function leap_year(y,jul)
if (not y) or (type(y) ~= "number")
then return false
elseif (y % 4) ~= 0
then return false
elseif not jul and (y % 100 == 0 and y % 400 ~= 0)
then return false
else return true
end
end
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей
local function month_end_day (month,year,is_julian)
local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой
if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil
elseif month ~= 2 or not year then return month_end_day[month]
elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29
elseif month == 2 then return 28
else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях
end
end
local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year
if not chain then return false
elseif (not type(chain) == "table")
or (not inbord(chain.year,-9999,9999))
or (not inbord(chain.month,1,12))
or (not inbord(chain.day,1,31))
or chain.day > monthd[chain.month]
-- or chain.year == 0
then return false
elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul)
then return false
else return true end
-- check for other calendars needed?
end
local function ispartdate ( chain )
if not chain then return false
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
or inbord(chain.month,1,12)
or inbord(chain.day,1,31)) then return true
else return false
end
-- partial date
-- more detailed check for 31.02.0000 needed
-- check for other calendars needed
end
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
local function partdist(date1,date2)
local mont, dist = 0, 0
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
-- нужна доп. проверка частичных дат на корректность
if (inbord(d1m,1,12) or inbord(d2m,1,12))
and (d1m == "" or d2m == "") then
mont = purif(date1["month"] or date2["month"])
d1m, d2m = mont, mont
end
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
if d2m == d1m
then dist = d2d - d1d
else dist = monthd[d1m] - d1d + d2d
end
return dist
else return math.huge
end
end
local function dmdist(d1,d2)
local p1,p2 = math.huge,math.huge
if not not partdist(d1,d2) then
p1=partdist(d1,d2)
end
if not not partdist(d2,d1) then
p1=partdist(d2,d1)
end
-- if (not p1) or (not p2) then
-- return (p1 or "") .. (p2 or "")
-- else
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
-- end
end
-- 30) Блок функций для обработки ввода-вывода дат
local function undate(tbl)
if not tbl then return ""
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
end
end
-- функция для нормализации значений дат и перевода месяцев в числа
local function numerize(str)
if type(str) == "number" then
return math.floor(str)
elseif str == "" or str == nil or type(str) ~= "string" then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
for i=1, #mnlang do
if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then
return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)]
end
end
end
end
-- функция распознавания даты, переданной одной строкой
local function parse_date(date_string)
if type(date_string) ~= "string" or date_string == "" then return nil end
local out_date_str = {"","",""}
local error_data = {}
for i=1, #pattern do
local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1])
if (result_1 or "") > "" then
out_date_str[pattern[i].order[1]] = result_1
out_date_str[pattern[i].order[2]] = result_2
if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end
-- mw.log("Паттерн " .. i .. ", строка: " .. date_string)
break
end
end
local date = {
["day"] =numerize(out_date_str[1]),
["month"]=numerize(out_date_str[2]),
["year"] =numerize(out_date_str[3])}
return date --, error_data
end
----[[ УСТАРЕЛО ]]----
local numstr2date = function(numstr)
local format = "Y-m-d"
local iso_date = mwlang:formatDate(format,numstr)
local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
return dateout
end
--local numstr2date = function(numstr)
-- local nums = {}
-- local dateout = {}
-- for num in string.gmatch(numstr,"(%d+)") do
-- table.insert(nums,purif(num))
-- end
-- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
-- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
-- elseif not inbord(nums[3],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- elseif not inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
-- elseif inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- else
-- local mwlang = mw.getContentLanguage()
-- implement mwlang:formatDate(format,datein,true) here
-- return error("Не распознано " .. numstr .. " как дата")
-- end
-- return dateout
--end
local function year2lang(numyear,yearmark,wiki)
if not numyear then return "" end
if not yearmark then yearmark = "" end
local output = ""
local bcmark = " до н. э."
if numyear > 0 then bcmark = ""
else numyear = 1 - numyear end
if wiki then
-- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'})
else
output = tCon({numyear, " ", yearmark, bcmark})
end
return trim(output)
end
local function day2lang(datein,wikidate,wiki,inner_brt)
-- if not isdate(wikidate) then wiki = false end
if not ispartdate(datein) then return "" end
local dm_separ, output = "", nil
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not datein.month) then datein.month = "" end
if (not datein.day) then datein.day = "" end
local monlan = monthlang[datein.month] or ""
if wiki and not inner_brt then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan, "]]"})
elseif wiki then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan})
else
output = tCon({datein.day, dm_separ, monlan})
end
return trim(output)
end
local function triple_txt2date(d,m,y)
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
-- mw.ustring.match((m or ""),"(%a+)")
local msg = ""
local year = purif((y or "-"):match("(%d+)"))
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
local day = purif((d or "-"):match("(%d+)"))
if not month then
msg = category.incomplete_parameters
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
end
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
msg = category.incomplete_parameters
day = purif(m:match("(%d+)") or "")
end
if not year then
msg = category.incomplete_parameters
year = purif(string.match(m or "","(%d+)") or "")
end
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
return dateout
end
local function glue(d1,m1,y1,d2,m2,y2)
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
return category.incomplete_parameters end
local gd,gm,gy,jd,jm,jy =
(d1 or ""),
(m1 or ""),
(y1 or ""),
(d2 or ""),
(m2 or ""),
(y2 or "")
--mw.log(tCon({gd,gm,gy,jd,jm,jy}))
local gm_sep = {" [["," год|","]]"}
if (not gy) or (gy == "") then gm_sep = {"","",""} end
return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""),
gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters})
end
-- добавить отображение без года
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
local msg = ""
msg = (jdate.msg or "") .. (gdate.msg or "")
local cd = {}
local jd = shallowcopy(jdate)
local gd = shallowcopy(gdate)
local left = "("
local right = ")"
if sq_brts then
left = "["
right = "]"
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
if jd.year == gd.year then
cd.year = gd.year
gd.year, jd.year = nil, nil
end
if jd.month == gd.month then
cd.month = gd.month
gd.month, jd.month = nil, nil
end
if (not not cd.month) and wm then
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
local function gri2jd( datein )
if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1931076.5, 5373557.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2jul( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local c = jd + 32082
local d = math.floor((4*c + 3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e + 2)/153)
local year_out = d - 4800 + math.floor(m/10)
local month_out = m + 3 - 12*math.floor(m/10)
local day_out = e - math.floor((153*m + 2)/5) + 1
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function jul2jd( datein )
if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - 32083
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1930999.5, 5373484.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2gri( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local a = jd + 32044
local b = math.floor((4*a + 3) / 146097)
local c = a - math.floor(146097*b/4)
local d = math.floor((4*c+3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e+2)/153)
local day_out = e - math.floor((153*m+2)/5)+1
local month_out = m + 3 - 12*math.floor(m/10)
local year_out = 100*b + d - 4800 + math.floor(m/10)
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function astroyear(num, bc)
if not num then return error()
elseif type(num) ~= "number" then return error()
end
if num < 1 then return num end
if not bc then return num
else return 1 - num
end
end
local function recalc(datein,calend)
if inlist(calend,params[1]) then
return jd2jul(gri2jd(datein)), datein
elseif inlist(calend,params[2]) then
return datein, jd2gri(jul2jd(datein))
else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," "))
end
end
-- 50) Функции для обработки UTC
local function utc(str,margin)
local d = 1
local dchar = "+"
local beginning = "[[UTC"
local ending = "]]"
local cat = ""
local nums = {}
local hmarg, timedec = 0, 0
local mmarg = "00"
local output = ""
-- checking type of input
if not margin then margin = 0
elseif type(tonumber(margin)) ~= 'number' then
output = "Can't shift by " .. margin
error(output)
end
if type(str) ~= 'string' then
error("Нет входящей строки")
elseif str:byte(1) == 43 then
elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]"
elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1
else
error(string.char(str:byte(1)) .. " недопустимый первый символ")
end
-- parsing input
for num in string.gmatch(str,"(%d+)") do
table.insert(nums,purif(num))
end
if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums)
elseif #nums == 0 then error("Необходимо что-то ввести")
elseif #nums == 1 then
if inbord(nums[1],0,14) then timedec = d*nums[1] + margin
else error("Только часы от -14 до 14") end
elseif #nums == 2 then
if not inbord(nums[1],0,14) then error("Только часы от -14 до 14")
elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59")
else
timedec = d*(nums[1] + nums[2]/60) + margin
end
end
if tonumber(timedec) == purif(timedec) then hmarg = timedec
else
local h, m = math.modf(math.abs(timedec))
hmarg = h
mmarg = math.floor(m*60)
end
if timedec == 0 then
dchar = "±"
elseif timedec > 0 then
elseif timedec < 0 then
dchar = "−"
end
-- output
output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat
return output
end
-- 60) Блок функций ввода-вывода
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num, wday, mont, yea, format =
purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
if not format then format = "%d.%m.%y" end
if not inbord(num,-5,5) then
return error("The number must be between -5 and 5")
elseif num == 0 then
return error("The number must not be zero") end
if not inbord(wday,0,6) then
return error("The day of the week must be between 0 and 6") end
if not inbord(mont,1,12) then
return error("The month must be between 1 and 12") end
if not inbord(yea,0,9999) then
return error("Wrong year number") end
if inbord(num,1,5) then
local m_start = os.time{year=yea, month=mont, day=1, hour=0}
local m_wds = tonumber(os.date("%w", m_start))
local start_shift = (
(num - bool_to_number[wday >= m_wds]) * 7
- (m_wds - wday)
) * 24 * 60 * 60
local tim = m_start + start_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
elseif inbord(num,-5,-1) then
local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
local m_wde = tonumber(os.date("%w", m_end))
local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
+ (m_wde - wday)) * 24 * 60 * 60
local tim = m_end - end_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
end
end
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
function p.ToIso( frame )
local args = getArgs(frame, { frameOnly = true })
local datein = args[1]
-- инициализация, заполнение обратных таблиц, копирование параметров
filling_months(mnlang, month_lang)
-- парсинг входящей даты по шаблону
local date = parse_date(datein)
if not (type(date.year) == 'number') then
return ("Wrong year: " .. unwarp(date))
end
if not (1 <= date.month and date.month <= 12) then
return ("Wrong month: " .. unwarp(date))
end
if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then
return ("Wrong day: " .. unwarp(date))
end
local timedate = os.time{year=date.year, month=date.month, day=date.day}
local date = os.date("%Y-%m-%d", timedate)
return date
end
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}})
function p.BoxDate( frame )
local args = getArgs(frame, { frameOnly = true })
local txtDateIn, strFormat = args[1], args[2]
local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
function p.bxDate( txtDateIn , strFormat, params ) -- к отладке
local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""}
strFormat = strFormat or "j xg Y"
-- заглушка - таблица параметров на будущее
params = params or {}
if not txtDateIn then
status.errorText = e.no_data
status.errorCat = category.no_parameters
status.brk = true
else
-- заполнение служебных таблиц
filling_months(mnlang, month_lang)
end
if not status.brk then
-- парсинг входящей даты по шаблону
date = parse_date(txtDateIn)
-- заменить сообщения об ошибках на списочные
if not (date.year and type(date.year) == 'number') then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not inbord(date.month,1,12) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not date.day and string.find(strFormat,"[dDjlNwzW]") then
strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]",""))
elseif not date.day then
elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
end
if not status.brk then
txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true)
end
return txtDateOut, date, status
end
function p.ToDate( frame ) -- возможно неиспользуемая
local args = getArgs(frame, { frameOnly = true })
local mwlang = mw.getContentLanguage()
local datein = args[1]
local format = "j xg Y"
if not string.match(datein, "%p") then return datein
elseif not args[2] then
else format = args[2]
end
return mwlang:formatDate(format,datein,true)
end
-- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}})
function p.unitime( frame )
local args = getArgs(frame, { frameOnly = true })
local DST = 0
if not args[2] then
else DST = 1 end
local utcin = ""
local input = args[1]
if not input then return "" end
if inlist(input:upper(),tzs_names) then
utcin = known_tzs[input:upper()]
elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
utcin = string.sub(input,4)
else
if string.sub(input,1,1) == '['
or string.sub(input,1,1) == '{'
or string.sub(input,1,1):upper() == 'U'
or string.sub(input,1,1):upper() == 'M' then
return input
-- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or
-- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then
-- return input
else utcin = input end
end
-- elseif string.sub(input,1,3) ~= "−" then utcin = input
-- or not (not input:find("[А-я]")) при наличии в строке юникода не работает
local output = ""
if DST == 0 then output = utc(utcin)
else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST)
end
return output
end
-- УСТАРЕЛО
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
function p.OldDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local gdate, jdate = {}, {}
local strin = args[1]
local cal = args[2]:lower() or "г"
local bc = is(args["bc"])
local wd = is(args["wd"])
local wm = is(args["wm"])
local wy = is(args["wy"])
if not wd then wm = false end
local sq_brts = is(args["sq_brts"])
local yearmark = "года"
if yesno(args["yearmark"]) then
elseif yesno(args["yearmark"]) == false then yearmark = ""
else yearmark = trim(args["yearmark"]) or "года" end
-- local infocard = is(args["infocard"])
-- local catName = args["catName"] or false
local datein = numstr2date(strin)
datein.year = astroyear(datein.year, bc)
jdate, gdate = recalc(datein,cal)
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
function p.NewDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local strin = args[1]
local year, month, day
if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then
year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" )
elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then
year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" )
elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then
day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" )
elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then
day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" )
end
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
end
local cal = "г"
if (not args[2]) or (args[2] == "") then cal = "г"
else cal = args[2]:lower() end
local bc,wd,wm,wy,sq_brts =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"])
year = astroyear(purif(year),bc)
local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
local jdate, gdate = recalc(datein,cal)
local yearmark = "года"
local ym = args["yearmark"] or ""
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
function p.Test( frame )
local args = getArgs(frame, { frameOnly = true })
-- необходима проверка и замена nil на " "
--[[mw.log((args[1] or "") .. " " ..
(args[2] or "") .. " " ..
(args[3] or "") .. " " ..
(args[4] or "") .. " " ..
(args[5] or "") .. " " ..
(args[6] or "")) ]]--
local ingdate = triple_txt2date(args[1],args[2],args[3])
local injdate = triple_txt2date(args[4],args[5],args[6])
local j1date, g1date, j2date, g2date = init(4)
mw.log("ingdate-".. (undate(ingdate) or ""))
mw.log("injdate-".. (undate(injdate) or ""))
local bc,wd,wm,wy,sq_brts,ny =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"]),
is(args["ny"])
-- подавление формата для локальных тестов
local wd, wm, wy = true, true, true
local yearmark = "года"
local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
-- mw.log("ym " .. ym)
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
if isdate(ingdate) or isdate(injdate) then
if isdate(ingdate) then
j1date, g1date = recalc(ingdate,"g")
ingdate["full"] = true
end
if isdate(injdate) then
j2date, g2date = recalc(injdate,"j")
injdate["full"] = true
end
if ispartdate(ingdate) and ispartdate(injdate) then
mw.log("📏 " .. dmdist(ingdate,injdate))
mw.log("📏 " .. dmdist(j1date,g1date))
mw.log("📏 " .. dmdist(j2date,g2date))
mw.log("📏 " .. dmdist(ingdate,g1date))
mw.log("📏 " .. dmdist(injdate,j2date))
end
end
if ny then
if isyear(j1date) then
else j1date["year"] = "" end
if isyear(j2date) == nil then
else j2date["year"] = "" end
if isyear(g1date) == nil then
else g1date["year"] = "" end
if isyear(g2date) == nil then
else g2date["year"] = "" end
end
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
if ((j1date.year == j2date.year)
and (j1date.month == j2date.month)
and (j1date.day == j2date.day)) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
else
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- категория (предположительная разница в днях) и частичный вывод
end
elseif isdate(j1date) and isdate(g1date) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif isdate(j2date) and isdate(g2date) then
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- частичный или полный вывод, категория
else
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
return err .. category.incomplete_parameters
end
end
return p
a4a91f134ad3e3b246b3a6681a4ae438da766df4
Шаблон:Число
10
94
198
2023-06-20T10:24:09Z
wikipedia, ruwikipedia>Stjn
0
лучше так тогда для лимитов
wikitext
text/x-wiki
{{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1= {{{2|}}}}} }} }}<noinclude>
{{doc}}
</noinclude>
acfc1e9cec817e6742b18106f020ac388ececc7e
Шаблон:Карточка/оригинал названия
10
89
188
2023-07-04T10:53:52Z
wikipedia, ruwikipedia>Wikisaurus
0
wikitext
text/x-wiki
{{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!--
-->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude>
4eccda042428e1113ff320ff5d6b760a7f52b088
Шаблон:Государство
10
106
222
2023-07-18T14:45:13Z
ruwikipedia>Krestenti
0
wikitext
text/x-wiki
{{Карточка
|имя = Государство
|автозаголовки = да
|from = {{{from|}}}
|вверху0 = {{#switch: {{{Статус|}}}
| виртуальное = [[Виртуальное государство]]
| особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }}
| Непризнанное
| непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }}
| Частично признанное
| частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }}
}}
|вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}}
|вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}}
|изображение = {{Карточка/флаг и герб
| флаг = {{{Флаг|}}}
| флаг ширина = {{{Размер флага|}}}{{{размер флага|}}}
| флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]]
| герб = {{{Герб|}}}
| герб ширина = {{{Размер герба|}}}{{{размер герба|}}}
| герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }}
|from={{{from|}}}}}
|текст1 = {{br separated entries
| {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }}
| {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }}
}}
|текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }}
|текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }}
|заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }}
|стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left;
|блок5 =
{{Карточка/блок с маркерами
|метка1 = {{nobr|{{{Дата1}}}}}
|текст1 = {{{Этап1|}}}
|метка2 = {{nobr|{{{Дата2}}}}}
|текст2 = {{{Этап2|}}}
|метка3 = {{nobr|{{{Дата3}}}}}
|текст3 = {{{Этап3|}}}
|метка4 = {{nobr|{{{Дата4}}}}}
|текст4 = {{{Этап4|}}}
|метка5 = {{nobr|{{{Дата5}}}}}
|текст5 = {{{Этап5|}}}
|метка6 = {{nobr|{{{Дата6}}}}}
|текст6 = {{{Этап6|}}}
|метка7 = {{nobr|{{{Дата7}}}}}
|текст7 = {{{Этап7|}}}
|метка8 = {{nobr|{{{Дата8}}}}}
|текст8 = {{{Этап8|}}}
|метка9 = {{nobr|{{{Дата9}}}}}
|текст9 = {{{Этап9|}}}
|метка10 = {{nobr|{{{Дата10}}}}}
|текст10 = {{{Этап10|}}}
|метка11 = {{nobr|{{{Дата11}}}}}
|текст11 = {{{Этап11|}}}
|метка12 = {{nobr|{{{Дата12}}}}}
|текст12 = {{{Этап12|}}}
|from={{{from|}}}}}
|заголовок6 = -
|метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]]
|текст7 = {{{Основана|}}}{{{Основано|}}}
|викиданные7 =
<!-- СПОРНЫЙ СТАТУС -->
<!-- Спорный статус заполнен -->
|метка8 = [[Основание государства|Дата образования]]
|текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }}
|викиданные8 =
|метка9 = Провозглашение независимости
|текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные9 =
|метка10 = [[Международно-правовое признание|Дипломатическое признание]]
|текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }}
|викиданные10 =
<!-- Спорный статус не заполнен -->
|метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }}
|текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные11 =
<!-- / СПОРНЫЙ СТАТУС -->
|метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]]
|текст12 = {{{Язык|{{{Языки|}}}}}}
|викиданные12 = p37
|метка13 = [[Столица]]
|текст13 = {{{Столица|}}}
|викиданные13 = p36
|метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }}
|текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}}
|викиданные14 =
|метка15 = [[Форма государственного правления|Форма правления]]
|текст15 = {{{Форма правления|}}}
|викиданные15 =
|метка16 = [[Форма государственного устройства|Государственный строй]]
|текст16 = {{{Государственный строй|}}}
|метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}}
|текст17 = {{{Руководитель 1|{{{Руководители|}}}}}}
|метка18 = {{{Должность руководителя 2}}}
|текст18 = {{{Руководитель 2|}}}
|метка19 = {{{Должность руководителя 3}}}
|текст19 = {{{Руководитель 3|}}}
|метка20 = {{{Должность руководителя 4}}}
|текст20 = {{{Руководитель 4|}}}
|метка21 = {{{Должность руководителя 5}}}
|текст21 = {{{Руководитель 5|}}}
|метка22 = {{{Должность руководителя 6}}}
|текст22 = {{{Руководитель 6|}}}
|метка23 = [[Государственная религия|Гос. религия]]
|текст23 = {{{Государственная религия|}}}
|викиданные23 =
|блок24 =
{{Карточка/блок с маркерами
|подзаголовок = [[Территория государства|Территория]]
|метка1 = Всего
|текст1 = {{br separated entries
| {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | {{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }}
| {{число|{{{Территория2|}}}|км²}}
}}
|метка2 = % водной поверхности
|текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }}
|from={{{from|}}}}}
|блок25 =
{{Карточка/блок с маркерами
|подзаголовок = [[{{Население государства|{{PAGENAME}}}}]]
|метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }}
|текст1 = {{br separated entries
| {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | ([[Список стран по населению|{{{Место по населению}}}-е]]) }}
| {{число|{{{Население2|}}}|чел.}}
}}
|метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }}
|текст2 = {{число|{{{Население по переписи|}}}|чел.}}
|метка3 = [[Плотность населения|Плотность]]
|текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | ([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }}
|from={{{from|}}}}}
|блок26 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]]
|метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }}
|текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок27 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }}
|текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок28 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }}
|текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | ([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | ([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }}
|текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | ({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | ; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е место]] }}) }}
|викиданные29 =
|метка30 = [[Названия жителей]]
|текст30 = {{{Этнохороним|}}}
|викиданные30 =
|метка31 = [[Валюта]]
|текст31 = {{{Валюта|}}}
|викиданные31 = P38
|метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]]
|текст32 = {{{Домен|}}}{{{Домены|}}}
|викиданные32 = P78
|метка33 = [[ISO 3166-1|Код ISO]]
|текст33 =
|викиданные33 = P297
|метка34 = [[Список кодов МОК|Код МОК]]
|текст34 =
|викиданные34 = P984
|метка35 = [[Список телефонных кодов стран|Телефонный код]]
|текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }}
|викиданные35 = P474
|метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]]
|текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}}
|викиданные36 = P421
|метка37 = Автомобильное движение
|текст37 = {{{Автомобильное движение|}}}
|викиданные37 = P1622
|текст38 = {{{Примечания|}}}
|стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{карточка/Викисклад|from={{{from|}}}}}
}}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{lat_deg|}}}
| {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}}
| {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }}
}}<!--
-->{{#switch: {{{Статус|}}}
| Виртуальное
| виртуальное = [[Категория:Виртуальные государства]]
| Непризнанное
| непризнанное = [[Категория:Непризнанные государства]]
| Частично признанное
| частично признанное = [[Категория:Частично признанные государства]]
| особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }}
| [[Категория:Государства по алфавиту]]
}}<!--
-->{{Государство/Викиданные}}
}}<noinclude>{{doc}}</noinclude>
d5532838af5967020fc4f653452458ba05aea4cf
Шаблон:Скрытый блок
10
51
112
2023-12-21T00:36:59Z
wikipedia, ruwikipedia>Stjn
0
неактуальный параметр
wikitext
text/x-wiki
{{Начало скрытого блока
|id = {{{id|}}}
|тип = {{{тип|{{{type|}}}}}}
|состояние = {{{state|{{{состояние|collapsed}}}}}}
|класс_тела = {{{класс_тела|{{{класс тела|}}}}}}
|стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}
|рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}}
|заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}
|ссылка = {{{Ссылка|{{{ссылка|}}}}}}
|класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}}
|шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}}
|наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}}
|фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}}
|выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}
|стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}}
|класс_текста = {{{класс_текста|{{{класс текста|}}}}}}
|шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}}
|наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}}
|фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}}
|выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}}
|стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}}
{{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}}
{{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }}
{{Конец скрытого блока}}<noinclude>
{{doc}}
</noinclude>
792dc9fb2eb659877e2e758f4ce405e1d3f8352b
Модуль:Navbox
828
33
76
2024-02-23T14:27:31Z
wikipedia, ruwikipedia>Stjn
0
переход на [[модуль:Navbar]]
Scribunto
text/plain
--
-- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}.
-- Основной объём кода заимствован из английского Module:Navbox.
--
local p = {}
local navbar = require('Module:Navbar')._ruwikiNavbar
local getArgs -- lazily initialized
local yesno -- lazily initialized
local styleratio
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
-- общие параметры для всех шаблонов
local commonAliases = {
name = {'name', 'имя'},
navigation = {'navigation', 'навигация'},
navbar = {'navbar', 'ссылка_на_просмотр'},
state = {'state'},
orphan = {'orphan'},
tracking = {'tracking'},
border = {'border', 1},
title = {'title', 'заголовок'},
titlegroup = {'titlegroup'},
above = {'above', 'вверху'},
image = {'image', 'изображение'},
imageleft = {'imageleft', 'изображение2', 'изображение_слева'},
below = {'below', 'внизу'},
bodyclass = {'bodyclass', 'класс_тела'},
titleclass = {'titleclass', 'класс_заголовка'},
titlegroupclass = {'titlegroupclass'},
aboveclass = {'aboveclass', 'класс_вверху'},
belowclass = {'belowclass', 'класс_внизу'},
groupclass = {'groupclass', 'класс_групп'},
listclass = {'listclass', 'класс_списков'},
imageclass = {'imageclass', 'класс_изображения'},
basestyle = {'basestyle', 'стиль', 'стиль_базовый'},
bodystyle = {'style', 'bodystyle', 'стиль_тела'},
titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'},
titlegroupstyle = {'titlegroupstyle'},
innerstyle = {'innerstyle'},
abovestyle = {'abovestyle', 'стиль_вверху'},
belowstyle = {'belowstyle', 'стиль_внизу'},
imagestyle = {'imagestyle', 'стиль_изображения'},
imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}}
local standardAliases = {
groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'},
liststyle = {'liststyle', 'стиль_списков'},
evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'},
groupwidth = {'groupwidth', 'ширина_групп'},
listpadding = {'listpadding', 'отступ_списков'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией
local standardElementAliases = {
group = {'group%s', 'заголовок%s', 'группа%s'},
list = {'list%s', 'список%s'},
groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль_списка%s'},
listpadding = {'list%spadding'}
}
-- параметры {{навигационная таблица с блоками}}
-- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases
local groupsParentAliases = {
selected = {'selected', 'открытый_блок', 'развернуть'},
secttitlestyle = {'secttitlestyle', 'стиль_заголовков'},
_groupstyle = {'groupstyle', 'стиль_блоков'},
_liststyle = {'liststyle', 'стиль_списков', 'contentstyle'},
_listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'}
}
-- параметры {{навигационная таблица с блоками}} с нумерацией
local groupsChildAliases = {
groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'},
state = {'state%s'},
title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'},
list1 = {'list%s', 'список%s', 'content%s'},
image = {'image%s', 'изображение%s'},
imageleft = {'imageleft%s', 'изображение_слева%s'},
secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'},
groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'},
color = {'цвет%s'}
}
local function checkAliases(args, aliases, index)
for _, alias in ipairs(aliases) do
local arg
if index then
arg = args[string.format(alias, index)]
else
arg = args[alias]
end
if arg then
return arg
end
end
return nil
end
local function checkElAliases(args, name, index)
return checkAliases(args, standardElementAliases[name], index)
end
local function concatStyles(t)
local res
for k, v in pairs(t) do
if v then
res = res and res .. ';' .. v or v
end
end
return res
end
local function striped(wikitext, args)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]'
if args.border == 'subgroup' and args.orphan ~= 'yes' then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = 'odd', 'even'
if args.evenodd then
if args.evenodd == 'swap' then
first, second = second, first
else
first = args.evenodd
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count
end
local function addNewline(s)
if s:match('^[*:;#]') or s:match('^{|') then
return '\n' .. s ..'\n'
else
return s
end
end
local function renderNavBar(titleCell, args)
local currentFrame = mw.getCurrentFrame()
if args.navbar ~= 'off' and args.navbar ~= 'plain'
and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then
--- Gear creation
titleCell
:tag('span')
:addClass('navbox-gear')
:css('float', 'left')
:css('text-align', 'left')
:css('width', '5em')
:css('margin-right', '0.5em')
:wikitext(navbar{
args.name,
['fontstyle'] = args.titlestyle or args.basestyle
})
end
end
--
-- Title row
--
local function renderTitleRow(tbl, args)
if not args.title then return end
local titleRow = tbl:tag('tr')
if args.titlegroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
:cssText(args.groupstyle)
:cssText(args.titlegroupstyle)
:wikitext(args.titlegroup)
end
local titleCell = titleRow:tag('th'):attr('scope', 'colgroup')
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
:cssText(args.basestyle)
:cssText(args.titlestyle)
:addClass('navbox-title')
:attr('colspan', titleColspan)
renderNavBar(titleCell, args)
titleCell
:tag('div')
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 5em')
:wikitext(addNewline(args.title))
end
--
-- Above/Below rows
--
local function getAboveBelowColspan(args)
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl, args)
if not args.above then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.above))
end
local function renderBelowRow(tbl, args)
if not args.below then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.below))
end
--
-- List rows
--
local function haveSubgroups(args)
for i = 1, 23 do
if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then
return true
end
end
return false
end
local function renderListRow(tbl, args, index, rowspan, rowArgs)
local row = tbl:tag('tr')
if index == 1 and args.imageleft then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 7px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.imageleft))
end
if rowArgs.group then
local groupCell = row:tag('th')
groupCell
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.groupclass)
:cssText(args.basestyle)
:css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width
groupCell
:cssText(args.groupstyle)
:cssText(rowArgs.groupstyle)
:wikitext(rowArgs.group)
end
local listCell = row:tag('td')
if rowArgs.group then
listCell
:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
if haveSubgroups(args) then
listCell
:attr('colspan', 2)
end
end
if not args.groupwidth then
listCell:css('width', '100%')
end
local listText = rowArgs.list
local oddEven = ODD_EVEN_MARKER
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
end
listCell
:css('padding', '0px')
:cssText(args.liststyle)
:cssText(rowArgs.liststyle)
:addClass('navbox-list')
:addClass('navbox-' .. oddEven)
:addClass(args.listclass)
:addClass(rowArgs.listclass)
:tag('div')
:css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em')
:wikitext(addNewline(listText))
if index == 1 and args.image then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 0px 0px 7px')
:cssText(args.imagestyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.image))
end
end
--
-- Tracking categories
--
local function needsChangetoSubgroups(args)
for i = 1, 23 do
if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then
return true
end
end
return false
end
local function needsHorizontalLists(args)
if args.border == 'subgroup' or args.tracking == 'no' then
return false
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
-- local function hasBackgroundColors()
-- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background')
-- end
local function isIllegible(args)
if not styleratio then
styleratio = require('Module:Color contrast')._styleratio
end
for key, style in pairs(args) do
if tostring(key):match("style$") or tostring(key):match("^стиль") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(args)
local cats = {}
if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end
if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end
if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end
return cats
end
local function renderTrackingCategories(builder, args)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end
for i, cat in ipairs(getTrackingCategories(args)) do
builder:wikitext('[[Категория:' .. cat .. ']]')
end
end
--
-- Main navbox tables
--
local function renderMainTable(args, listnums)
local tbl = mw.html.create('table')
:addClass('nowraplinks')
:addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
:addClass('collapsible')
:addClass(args.state or 'autocollapse')
end
tbl:css('border-spacing', 0)
if args.border == 'subgroup' or args.border == 'none' then
tbl
:addClass('navbox-subgroup')
:cssText(args.bodystyle)
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args.innerstyle)
renderTitleRow(tbl, args)
renderAboveRow(tbl, args)
for i, listnum in ipairs(listnums) do
local rowArgs = {
group = checkElAliases(args, 'group', listnum),
list = checkElAliases(args, 'list', listnum),
groupstyle = checkElAliases(args, 'groupstyle', listnum),
listclass = checkElAliases(args, 'listclass', listnum),
liststyle = checkElAliases(args, 'liststyle', listnum),
listpadding = checkElAliases(args, 'listpadding', listnum)
}
renderListRow(tbl, args, i, #listnums, rowArgs)
end
renderBelowRow(tbl, args)
return tbl
end
-- Read the arguments in the order they'll be output in, to make references number in the right order.
local function readInTheRightOrder(args, groupAliases, listAliases)
local _
_ = checkAliases(args, commonAliases.title)
_ = checkAliases(args, commonAliases.above)
for i = 1, 23 do
_ = checkAliases(args, groupAliases, i)
_ = checkAliases(args, listAliases, i)
end
_ = checkAliases(args, commonAliases.below)
end
function p._navbox(args)
if not yesno then
yesno = require('Module:Yesno')
end
local listnums = {}
for k, v in pairs(args) do
local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
table.sort(listnums)
args.border = mw.text.trim(args.border or args[1] or '')
if args.border == 'child' then
args.border = 'subgroup'
end
for argname, aliasesList in pairs(commonAliases) do
args[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(standardAliases) do
args[argname] = checkAliases(args, aliasesList)
end
args.navigation = yesno(args.navigation, '')
-- render the main body of the navbox
local tbl = renderMainTable(args, listnums)
-- render the appropriate wrapper around the navbox, depending on the border param
local res = mw.html.create()
if args.border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
elseif args.border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
:node(tbl)
:wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:cssText(args.bodystyle)
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
end
renderTrackingCategories(res, args)
return striped(tostring(res), args)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
if not yesno then
yesno = require('Module:Yesno')
end
args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}})
if frame.args.border then
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
args.border = frame.args.border
end
readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list)
return p._navbox(args)
end
function p.navboxWithCollapsibleGroups(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}})
readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1)
local parent = {}
for argname, aliasesList in pairs(commonAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(groupsParentAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for i = 1, 20 do
local child = {}
for argname, aliasesList in pairs(groupsChildAliases) do
child[argname] = checkAliases(args, aliasesList, i)
end
child.color = child.color and string.format('background:%s;', child.color) or ''
child.border = 'child'
child.navbar = 'plain'
if parent.selected and parent.selected == child.groupname then
child.state = 'uncollapsed'
end
child.state = child.state or 'collapsed'
child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle}
child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color}
child.liststyle = concatStyles{parent._liststyle, child.liststyle}
child.lispadding = parent._listpadding
if child.title then
parent['list' .. i] = p._navbox(child)
else
parent['list' .. i] = child.list1
end
end
return p._navbox(parent)
end
return p
cf72974326d19e1d4d58d2d00766b944b3ca0944
Шаблон:Навигационная таблица
10
37
84
2024-02-26T11:53:15Z
wikipedia, ruwikipedia>Stjn
0
тоже может иметь эти значения
wikitext
text/x-wiki
<includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон
| {{#switch: {{{1|{{{border|}}}}}}
| child | subgroup | none =
| {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}}
|
| {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}}
|
| {{#if: {{{имя|{{{name|}}}}}}
| {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}}
| [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]]
}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c
Модуль:Message box
828
15
40
2024-03-25T18:05:03Z
wikipedia, ruwikipedia>Stjn
0
fix
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('mbox-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
if args.sect and args.sect ~= '' or nil then
local issue_sect = args.issue_sect
issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil
local text_sect = args.text_sect
text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil
local issues = {}
table.insert(issues, issue_sect)
table.insert(issues, text_sect)
self.issue = table.concat(issues, ' ')
else
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
if self.isSmall then
self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Conditional TemplateStyles loading
if self.base_templatestyles then
local frame = mw.getCurrentFrame()
root:wikitext(frame:extensionTag{
name = 'templatestyles',
args = { src = self.base_templatestyles },
})
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle)
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.fix and (' ' .. self.fix) or nil)
:wikitext(self.talk and (' ' .. self.talk) or nil)
end
if self.textsmall or self.fix or self.talk then
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
else
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
end
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f2539b657a9cdadde7c0dd5ad270d3095b2bdd54
Шаблон:Очистить кэш
10
61
132
2024-03-27T11:58:48Z
wikipedia, ruwikipedia>Stjn
0
не помещать на все страницы ежедневную очистку кэша
wikitext
text/x-wiki
<!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}}
| {{ns:10}} <!-- Шаблон -->
| {{очищать кэш|ежедневно}}
}}<noinclude>{{doc}}</noinclude>
be6695060ca61d2125386d02d3a19109c0e7c27b
Модуль:Yesno
828
13
36
2024-03-30T22:30:54Z
wikipedia, ruwikipedia>Stjn
0
кириллическая у из-за невозможности различить от латинской
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
-- кириллица
or val == 'у'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
ae94e12a838e770797317ed07b57b330ffeb7658
Шаблон:Yesno-yes
10
36
82
2024-04-05T13:04:36Z
wikipedia, ruwikipedia>Stjn
0
подстановка
wikitext
text/x-wiki
{{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>
{{doc}}
</noinclude>
3792ff694708f98102e3a6d556abe73bedc29069
Шаблон:Выполнить скрипт
10
66
142
2024-04-07T13:34:28Z
wikipedia, ruwikipedia>Stjn
0
отключение старой схемы
wikitext
text/x-wiki
{{#switch: {{{1|}}}
| =
| mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]]
| #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }}
}}<noinclude>
{{doc}}
</noinclude>
6979ea0342067dc76b9adcb9a5e072207c2c5a63
Шаблон:СИШ
10
69
148
2024-04-07T23:07:09Z
wikipedia, ruwikipedia>Stjn
0
режет глаз
wikitext
text/x-wiki
<noinclude>{{к объединению|2020-11-10|Шаблон:High-use}}
</noinclude>{{ombox
|type = notice
|image = [[Файл:Stalewarning.svg|40px|alt=Время]]
|text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].'''
|text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений].
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude>
{{doc}}
</noinclude>
013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b
Шаблон:Replace
10
30
70
2024-04-14T07:24:11Z
wikipedia, ruwikipedia>Stjn
0
обновление аналогично английскому шаблону
wikitext
text/x-wiki
{{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude>
{{doc}}
</noinclude>
7752c3c70ae8c46a89a0808aa282956866dbba5b
Шаблон:Начало скрытого блока
10
43
96
2024-04-15T20:10:25Z
wikipedia, ruwikipedia>Stjn
0
см. [[phab:T185674#9715417]]
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!--
--><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!--
--><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!--
-->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!--
-->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!--
--><div class="mw-collapsible-toggle-placeholder"></div></div><!--
--><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!--
-->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!--
--></includeonly><noinclude>
{{doc}}
</noinclude>
3b96bb802b522e629c41cddc5d44dfb2a9eb462a
Модуль:Demo
828
103
216
2024-05-02T11:40:03Z
wikipedia, ruwikipedia>Vavilexxx
0
исправление
Scribunto
text/plain
local p = {}
local getArgs = require('Модуль:Arguments').getArgs
local function hasValue(param)
if param and param:find('%S') then
return true
end
end
--creates a frame object that cannot access any of the parent's args
--unless a table containing a list keys of not to inherit is provided
function disinherit(frame, onlyTheseKeys)
local parent = frame:getParent() or frame
local orphan = parent:newChild{}
orphan.getParent = parent.getParent --returns nil
orphan.args = {}
if onlyTheseKeys then
local family = {parent, frame}
for f = 1, 2 do
for k, v in pairs(family[f] and family[f].args or {}) do
orphan.args[k] = orphan.args[k] or v
end
end
parent.args = mw.clone(orphan.args)
setmetatable(orphan.args, nil)
for _, k in ipairs(onlyTheseKeys) do
rawset(orphan.args, k, nil)
end
end
return orphan, parent
end
function p.get(frame, arg, passArgs)
local orphan, frame = disinherit(frame, passArgs and {arg or 1})
local code, noWiki, preserve = frame.args[arg or 1] or ''
local kill_categories = not frame.args.save_categories
local tag, sep
if code:match'nowiki' then
local placeholder, preserve = ('6'):char(), {}
-- We replace "}%-" and "%-{" because of some server bug probably connected to
-- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to
-- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>'))
-- outputting '}-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>"
code = mw.text.unstripNoWiki(code)
:gsub('<', '<')
:gsub('>', '>')
:gsub('}%-', '}-')
:gsub('%-{', '-{')
if (mw.text.trim(code):match'\n') then
tag = 'pre'
sep = ''
end
noWiki = code:gsub('%%', placeholder)
for k in noWiki:gmatch('&.-;') do
table.insert(preserve, (k:gsub('&', '&')))
noWiki = noWiki:gsub('(&.-;)', '%%%s')
end
noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%')
end
return {
source = noWiki or code,
output = orphan:preprocess(code)
:gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[К:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame,
args = getArgs(frame),
tag = tag,
sep = sep
}
end
function p.main(frame, demoTable)
local show = demoTable or p.get(frame)
local args = show.args
local yesno = require('Module:Yesno')
args.reverse = yesno(args.reverse, false)
args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code"
args.sep = args.sep or args.br or show.sep
args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ')
if show[args.result_arg] then
return show[args.result_arg]
end
return args.reverse
and string.format(
'%s%s<%s%s%s>%s</%s>',
show.output,
args.sep,
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag
)
or string.format(
'<%s%s%s>%s</%s>%s%s',
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag,
args.sep,
show.output
)
end
--passing of args into other module without preprocessing
function p.module(frame)
local orphan, frame = disinherit(frame, {
'demo_template',
'demo_module',
'demo_module_func',
'demo_main',
'demo_br',
'demo_result_arg',
'demo_save_categories'
})
local template = frame.args.demo_template and 'Template:'..frame.args.demo_template
local demoFunc = frame.args.demo_module_func or 'main\n'
local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')]
frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg
local kill_categories = not save_categories
if demoModule then
local named = {insert = function(self, ...) table.insert(self, ...) return self end}
local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'}
if not template then
source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc)
end
local insertNamed = #source + 1
for k, v in pairs(orphan.args) do
local nan, insert = type(k) ~= 'number', {v}
local target = nan and named or source
target:insert'|'
if nan then
target:insert(k):insert'=':insert'\n'
table.insert(insert, 1, #target)
end
target:insert(unpack(insert))
local nowiki = v:match('nowiki')
if nowiki or v:match('{{.-}}') then
orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v)
end
end
source:insert'}}'
table.insert(source, insertNamed, table.concat(named))
return p.main(orphan, {
source = mw.text.encode(table.concat(source), "<>'|=~"),
output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame
})
else
return "ERROR: Invalid module function: "..demoFunc
end
end
return p
9beaf8f8041a39ae73ba17b2f70609171c4196d3
Шаблон:Действия для страницы/styles.css
10
57
124
2024-05-02T17:22:30Z
wikipedia, ruwikipedia>Stjn
0
fix
text
text/plain
.ts-tlinks-tlinks {
font-weight: normal;
float: right;
line-height: inherit;
}
.ts-tlinks-tlinks .mw-editsection-divider {
display: inline;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
a003e896d263c29e66d2246b210e5d73e577ea46
Шаблон:Действия для страницы
10
56
122
2024-05-02T17:24:27Z
wikipedia, ruwikipedia>Stjn
0
никаких пиксельных fontsize
wikitext
text/x-wiki
<templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!--
-->{{join|separator=<span class="mw-editsection-divider"> &#124; </span>
|1={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }}
}}
|2={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]]
}}
|3={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }}
}}
|4={{#ifexist: {{#rel2abs: {{{lc|}}} }}
|
| [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать]
}}
|5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }}
|6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }}
}}<span class="mw-editsection-bracket">]</span></div><noinclude>
{{doc}}
</noinclude>
9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4
Шаблон:OnLua
10
64
138
2024-05-07T19:08:37Z
wikipedia, ruwikipedia>MBH
0
MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua]]
b72371e7ae22239863c474a78238171c2bd94c7e
Шаблон:Lua
10
71
152
2024-05-07T19:08:37Z
wikipedia, ruwikipedia>MBH
0
MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]]
wikitext
text/x-wiki
<includeonly>{{ombox
| small = yes
| style = width:23em;
| image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]]
| text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|:<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}| с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из }}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!--
-->{{#invoke:Transclude|npc|OnLua/Строка|
module=
|function=
|tech=
|line=
}}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}}
}}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude>
f1fdaa87edb15d61e23e98f6e25d171a975e10eb
Шаблон:OnLua/Строка
10
67
144
2024-05-07T19:08:38Z
wikipedia, ruwikipedia>MBH
0
MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua/Строка]]
d7f869ccc7a7efc800399fce32bc75e0f91066de
Шаблон:Lua/Строка
10
74
158
2024-05-07T19:08:38Z
wikipedia, ruwikipedia>MBH
0
MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]]
wikitext
text/x-wiki
<includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из }}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude>
5a35837338c2daee2d240a8e5335e8fec8e7d87e
Шаблон:Дерево категорий
10
68
146
2024-05-17T22:35:29Z
wikipedia, ruwikipedia>QBA-bot
0
Защитил страницу [[Шаблон:Дерево категорий]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
<div>{{{title|'''Дерево категорий'''}}}
{{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}}
| mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}}
| depth = {{#if:{{{3}}}|{{{3}}}}}
}}
</div><noinclude>
{{doc}}
</noinclude>
9763d532ff7b79a638abe485875db984254b57db
Модуль:Sources
828
83
176
2024-06-10T20:41:59Z
wikipedia, ruwikipedia>Stjn
0
возврат, сломало [[Википедия:Форум/Технический#Ошибка lua]]
Scribunto
text/plain
---@alias args table
---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) }
---@alias source { publication: source, [string]: any }
---@alias value: string | { id: string }
---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } }
---@alias snaks table<string, table<number, snak>>
---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks }
---@alias statements table<string, table<number, statement>>
---@alias map { name: string, ids: string[] }[]>
---@type table
local p = {}
---@type table<string, string>
local NORMATIVE_DOCUMENTS = {
Q20754888 = 'Закон Российской Федерации',
Q20754884 = 'Закон РСФСР',
Q20873831 = 'Распоряжение Президента Российской Федерации',
Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации',
Q2061228 = 'Указ Президента Российской Федерации',
}
---@type table<string, string>
local LANG_CACHE = {
Q150 = 'fr',
Q188 = 'de',
Q1321 = 'es',
Q1860 = 'en',
Q652 = 'it',
Q7737 = 'ru',
Q8798 = 'uk',
}
---@type map
local PROPERTY_MAP = {
{ name = 'sourceId', ids = { 'P248', 'P805' } },
{ name = 'lang', ids = { 'P407', 'P364' } },
{ name = 'author', ids = { 'P50', 'P2093' } },
{ name = 'part', ids = { 'P958', 'P1810' } },
{ name = 'title', ids = { 'P1476' } },
{ name = 'subtitle', ids = { 'P1680' } },
{ name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } },
{ name = 'editor', ids = { 'P98' } },
{ name = 'translator', ids = { 'P655' } },
{ name = 'publication-id', ids = { 'P1433' } },
{ name = 'edition', ids = { 'P393' } },
{ name = 'publisher', ids = { 'P123' } },
{ name = 'place', ids = { 'P291' } },
{ name = 'volume', ids = { 'P478' } },
{ name = 'issue', ids = { 'P433' } },
{ name = 'dateOfCreation', ids = { 'P571' } },
{ name = 'dateOfPublication', ids = { 'P577' } },
{ name = 'pages', ids = { 'P304' } },
{ name = 'numberOfPages', ids = { 'P1104' } },
{ name = 'tirage', ids = { 'P1092' } },
{ name = 'isbn', ids = { 'P212', 'P957' } },
{ name = 'issn', ids = { 'P236' } },
-- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references
{ name = 'docNumber', ids = { 'P1545' } },
{ name = 'type', ids = { 'P31' } },
{ name = 'arxiv', ids = { 'P818' } },
{ name = 'doi', ids = { 'P356' } },
{ name = 'pmid', ids = { 'P698' } },
}
-- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier
---@type map
local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP )
---@type string[]
local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' }
---@type string
local i18nDefaultLanguage = mw.language.getContentLanguage():getCode()
p.i18nDefaultLanguage = i18nDefaultLanguage
---@type string
local i18nEtAlDefault = ' et al.'
---@type table<string, string>
local i18nEtAl = {
ru = ' и др.',
uk = ' та ін.',
}
---@type table<string, string>
local i18nEditors = {
fr = '',
de = 'Hrsg.: ',
es = '',
en = '',
it = '',
ru = 'под ред. ',
uk = 'за ред. ',
}
---@type table<string, string>
local i18nTranslators = {
fr = '',
de = '',
es = '',
en = '',
it = '',
ru = 'пер. ',
uk = 'пер. ',
}
---@type table<string, string>
local i18nVolume = {
de = 'Vol.',
fr = 'Vol.',
es = 'Vol.',
en = 'Vol.',
it = 'Vol.',
ru = 'Т.',
uk = 'Т.',
}
---@type table<string, string>
local i18nIssue = {
en = 'Iss.',
ru = 'вып.',
uk = 'вип.',
}
---@type table<string, string>
local i18nPages = {
fr = 'P.',
de = 'S.',
es = 'P.',
en = 'P.',
it = 'P.',
ru = 'С.',
uk = 'С.',
}
---@type table<string, string>
local i18nNumberOfPages = {
en = 'p.',
ru = 'с.',
}
---@type table<string, string>
local i18nTirage = {
en = 'ed. size: %d',
ru = '%d экз.',
}
---@param args args
---@return source
local function getFilledArgs( args )
---@type source
local data = {}
for key, value in pairs( args ) do
if mw.text.trim( value ) ~= '' then
if key == 1 then
key = 'sourceId'
end
data[ key ] = mw.text.trim( value )
end
end
return data
end
---Returns formatted pair {Family name(s), First name(s)}
---@param fullName string
---@return table<number, string>
local function tokenizeName( fullName )
local space = '%s+' -- matches single or more spacing character
local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot
local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot
local surnamePrefixes = { 'ван', 'van', 'де', 'de' }
local nm, nm2, srn, srn2, pref
fullName = ' ' .. fullName .. ' '
fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' )
fullName = mw.text.trim( fullName )
-- Surname, Name
local pattern = '^' .. surname .. ',' .. space .. name .. '$'
srn, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Surname, Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '.' }
end
end
-- Surname, Name Name
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$'
srn, nm, nm2 = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Surname Surname, Name
pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$'
srn, srn2, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn .. ' ' .. srn2,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Name Name Surname
pattern = '^' .. name .. space .. name .. space .. surname .. '$'
nm, nm2, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Name Name prefix Surname
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$'
nm, nm2, pref, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Surname, Name Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, nm2, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Name{1,4} Surname
for k = 1, 4 do
pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 1, k do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ k + 1 ],
table.concat( matched, '. ', 1, k ) .. '.'
}
end
end
-- Surname Name{1,4}
for k = 1, 4 do
pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 2, k + 1 do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ 1 ],
table.concat( matched, '. ', 2, k + 1 ) .. '.'
}
end
end
return { fullName }
end
---@param fullName string | nil
---@return string | nil
local function personNameToAuthorName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 1 ] .. ' ' .. tokenized[ 2 ]
end
---@param fullName string | nil
---@return string | nil
local function personNameToResponsibleName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 2 ] .. ' ' .. tokenized[ 1 ]
end
---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean }
---@type options
local options_commas = {
separator = ', ',
conjunction = ', ',
format = function( data ) return data end,
nolinks = false,
preferids = false,
short = false,
}
---@type options
local options_commas_short = mw.clone( options_commas )
options_commas_short.short = true
---@type options
local options_commas_it_short = mw.clone( options_commas_short )
options_commas_it_short.format = function( data ) return "''" .. data .. "''" end
---@type options
local options_commas_nolinks = mw.clone( options_commas )
options_commas_nolinks.nolinks = true
---@type options
local options_citetypes = {
separator = ' ',
conjunction = ' ',
format = function( data ) return 'citetype_' .. data end,
nolinks = true ,
preferids = true,
short = false,
}
---@type options
local options_commas_authors = mw.clone( options_commas )
options_commas_authors.format = personNameToAuthorName
---@type options
local options_commas_responsible = mw.clone( options_commas )
options_commas_responsible.format = personNameToResponsibleName
---@type options
local options_ids = {
separator = '; ',
conjunction = '; ',
format = function( id ) return id end,
nolinks = true,
preferids = false,
short = false,
}
---@type options
local options_arxiv = mw.clone( options_ids )
options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end
---@type options
local options_doi = mw.clone( options_ids )
options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end
---@type options
local options_issn = mw.clone( options_ids )
options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end
---@type options
local options_pmid = mw.clone( options_ids )
options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end
---@param str string | nil
---@return boolean
local function isEmpty( str )
return not str or #str == 0
end
---@param allQualifiers snaks
---@param qualifierPropertyId string
---@return string | nil
local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId )
if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then
return nil
end
---@type table<number, snak>
local propertyQualifiers = allQualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if ( qualifier
and qualifier.datatype == 'string'
and qualifier.datavalue
and qualifier.datavalue.type == 'string'
and qualifier.datavalue.value ~= ''
) then
return qualifier.datavalue.value
end
end
return nil
end
---@param data table
---@param resultProperty string
---@return void
local function appendImpl_toTable( data, resultProperty )
if not data[ resultProperty ] then
data[ resultProperty ] = {}
elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then
data[ resultProperty ] = { data[ resultProperty ] }
end
end
---@param datavalue table
---@param qualifiers snaks
---@param data table
---@param propertyName string
---@param options table
local function appendImpl( datavalue, qualifiers, data, propertyName, options )
data[ propertyName ] = data[ propertyName ] or {}
if propertyName == 'issn' then
table.insert( data[ propertyName ], datavalue.value )
elseif propertyName == 'url' or datavalue.type == 'url' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'string' then
local value = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not value then
value = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
if not value then
value = datavalue.value
if options.format then
value = options.format( value )
end
end
appendImpl_toTable(data, propertyName)
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
if pos then
table.insert( data[ propertyName ], tonumber(pos), value )
else
table.insert( data[ propertyName ], value )
end
elseif datavalue.type == 'monolingualtext' then
local value = datavalue.value.text
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'quantity' then
local value = datavalue.value.amount
if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then
value = mw.ustring.sub( value , 2 )
end
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'wikibase-entityid' then
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
local value = datavalue.value
appendImpl_toTable(data, propertyName)
local label = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not label then
label = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
local toInsert = {
id = value.id,
label = label
}
if pos and tonumber( pos ) then
table.insert( data[ propertyName ], tonumber( pos ), toInsert )
else
table.insert( data[ propertyName ], toInsert )
end
elseif datavalue.type == 'time' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], tostring( value.time ) )
end
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getAllStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getBestStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param projectToCheck string?
---@return string | nil
local function getSitelink( entityId, projectToCheck )
---@type boolean, string
local wbStatus, sitelink
if projectToCheck then
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck )
else
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId )
end
if not wbStatus then
return nil
end
return sitelink
end
---@param args any[]
---@return any | nil
local function coalesce( args )
for _, arg in pairs( args ) do
if not isEmpty( arg ) then return arg end
end
return nil
end
---@param value any
---@return string | nil
local function getSingle( value )
if type( value ) == 'string' then
return tostring( value )
elseif type( value ) == 'table' then
if value.id then
return tostring( value.id )
end
for _, tableValue in pairs( value ) do
return getSingle( tableValue )
end
end
return nil
end
---@param langEntityId string
---@return string | nil
local function getLangCode( langEntityId )
if not langEntityId then
return nil
end
langEntityId = getSingle( langEntityId )
if not string.match( langEntityId, '^Q%d+$' ) then
return langEntityId
end
local cached = LANG_CACHE[ langEntityId ]
if cached then
if cached == '' then
return nil
end
return cached
end
local claims = getBestStatements( langEntityId, 'P424' )
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
then
LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value
return claim.mainsnak.datavalue.value
end
end
LANG_CACHE[ langEntityId ] = ''
return nil
end
---@param entityId string
---@param propertyId string
---@param data source
---@param propertyName string
---@param options table?
---@return void
local function appendEntitySnaks( entityId, propertyId, data, propertyName, options )
options = options or {}
-- do not populate twice
if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then
return
end
local statements = getBestStatements( entityId, propertyId )
if propertyName == 'author' then
data[ propertyId ] = true
end
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
if propertyId == 'P1680' then -- if there is a default language
for _, statement in pairs( statements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.language == lang
then
--found default language string
appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options )
return
end
end
end
for _, statement in pairs( statements ) do
if statement and statement.mainsnak and statement.mainsnak.datavalue then
appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options )
if propertyName == 'publication-id' and statement.qualifiers then
data[ 'publication-qualifiers' ] = statement.qualifiers
end
end
end
end
---@param claims table<number, statement>
---@param qualifierPropertyId string
---@param result table
---@param resultPropertyId string
---@param options table
---@return void
local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options )
-- do not populate twice
if not claims or result[ resultPropertyId ] then
return
end
for _, claim in pairs( claims ) do
if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then
---@type table<number, snak>
local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if qualifier and qualifier.datavalue then
appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options )
end
end
end
end
end
---@param entityId string
---@param propertyId string
---@param value any
---@return table<number, statement>
local function findClaimsByValue( entityId, propertyId, value )
local result = {}
local claims = getAllStatements( entityId, propertyId )
for _, claim in pairs( claims ) do
if ( claim.mainsnak and claim.mainsnak.datavalue ) then
local datavalue = claim.mainsnak.datavalue
if ( datavalue.type == "string" and datavalue.value == value ) or
( datavalue.type == "wikibase-entityid" and
datavalue.value[ "entity-type" ] == "item" and
tostring( datavalue.value.id ) == value )
then
table.insert( result, claim )
end
end
end
return result
end
---@param entityId string
---@param typeEntityId string
---@return boolean
local function isInstanceOf( entityId, typeEntityId )
return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil
end
---@param entityId string
---@param typeEntityIds string[]
---@return string
---@todo Rewrite
local function getFirstType( entityId, typeEntityIds )
for _, typeEntityId in pairs( typeEntityIds ) do
if isInstanceOf( entityId, typeEntityId ) then
return typeEntityId
end
end
return nil
end
---@param snaks snaks
---@param data source
---@param map map
---@return void
local function populateDataFromSnaks( snaks, data, map )
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
if not data[ parameterName ] and snaks[ propertyId ] then
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
for _, snak in pairs( snaks[ propertyId ] ) do
if snak and snak.datavalue then
appendImpl( snak.datavalue, {}, data, parameterName, options )
end
end
end
end
end
end
---@param entityId string | nil
---@param data source
---@param map map
---@return void
local function populateDataFromEntity( entityId, data, map )
if not data.title then
if not isEmpty( entityId ) then
local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end }
appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks )
else
appendEntitySnaks( entityId, 'P1476', data, 'title', {} )
end
appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} )
end
local bookSeriesStatements = getBestStatements( entityId, 'P361' )
for _, statement in pairs( bookSeriesStatements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.id
then
local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id
if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then
appendImpl_toTable( data, 'bookSeries' )
table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } )
appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} )
appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} )
end
end
end
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
appendEntitySnaks( entityId, propertyId, data, parameterName, options )
end
end
end
---@param data source
---@return void
local function expandPublication( data )
if not data[ 'publication-id' ] then
return
end
local publicationId = getSingle( data[ 'publication-id' ] )
data.publication = {}
for key, value in pairs( data ) do
if not string.match( key, '^publication-' ) then
data.publication[ key ] = value
end
end
data.publication.sourceId = publicationId
data.publication.title = data[ 'publication-title' ]
data.publication.subtitle = data[ 'publication-subtitle' ]
if data[ 'publication-qualifiers' ] then
populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP )
end
populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP )
if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then
data.publication.title = data.publication.title[ 1 ]
end
if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then
data.publication.subtitle = data.publication.subtitle[ 1 ]
end
for key, value in pairs( data.publication ) do
if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then
data[ key ] = value
end
end
end
---@param data source
---@return void
local function expandBookSeries( data )
local bookSeries = data.bookSeries
if not bookSeries then
return
end
-- use only first one
if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then
data.bookSeries = bookSeries[ 1 ]
bookSeries = data.bookSeries
end
if not bookSeries or not bookSeries.id then
return
end
appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} )
appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} )
appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} )
end
---@param entityId string
---@return string | nil
local function getNormativeTitle( entityId )
local possibleTypeIds = {}
for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do
table.insert( possibleTypeIds, typeId )
end
local foundTypeId = getFirstType( entityId, possibleTypeIds )
if foundTypeId then
return NORMATIVE_DOCUMENTS[ foundTypeId ]
end
return nil
end
---@param urls table<number, string> | string
---@param text string
---@return string
local function wrapInUrl( urls, text )
local url = getSingle( urls )
if string.sub( url, 1, 1 ) == ':' then
return '[[' .. url .. '|' .. text .. ']]'
else
return '[' .. url .. ' ' .. text .. ']'
end
end
---@param entityId string
---@param lang string
---@return string
local function getElementLink( entityId, lang )
local sitelink = getSitelink( entityId, nil )
if sitelink then
return ':' .. sitelink
end
if lang ~= 'mul' then
-- link to entity in source language
sitelink = getSitelink( entityId, lang .. 'wiki' )
if sitelink then
return ':' .. lang .. ':' .. sitelink
end
end
return ':d:' .. entityId
end
---@param entityId string
---@param lang string
---@return string
local function getLabel( entityId, lang )
local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang )
if not wbStatus then
return ''
end
if label and label ~= '' then
return label
end
wbStatus, label = pcall( mw.wikibase.getLabel, entityId )
if not wbStatus then
return ''
end
return label or ''
end
---@param lang string
---@param entityId string
---@param customTitle string
---@param options table
local function renderLink( lang, entityId, customTitle, options )
if not entityId then
error( 'entityId is not specified' )
end
if type( entityId ) ~= 'string' then
error( 'entityId is not string, but ' .. type( entityId ) )
end
if type( customTitle or '' ) ~= 'string' then
error( 'customTitle is not string, but ' .. type( customTitle ) )
end
local title = customTitle
-- ISO 4
if isEmpty( title ) then
local propertyStatements = getBestStatements( entityId, 'P1160' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' )
break
end
end
end
-- official name P1448
-- short name P1813
if isEmpty( title ) and options.short then
local propertyStatements = getBestStatements( entityId, 'P1813' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' )
break
end
end
end
-- person name P1559
-- labels
if isEmpty( title ) then
title = getLabel( entityId, lang )
-- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' )
end
local actualText = title or '\'\'(untranslated)\'\''
local link = getElementLink( entityId, lang )
return wrapInUrl( link, actualText )
end
---@param lang string
---@param value value
---@param options options
---@return string
local function asString( lang, value, options )
if type( value ) == 'string' then
return options.format( value )
end
if type( value ) ~= 'table' then
return options.format( '(unknown type)' )
end
if value.id then
-- this is link
if type( value.label or '' ) ~= 'string' then
mw.logObject( value, 'error value' )
error( 'label of table value is not string but ' .. type( value.label ) )
end
local title
if options.preferids then
title = value.id
elseif options.nolinks then
title = value.label or getLabel( value.id, lang )
else
title = renderLink( lang, value.id, value.label, options )
end
if title == '' then
title = "''(untranslated title)''"
end
return options.format( title )
end
local resultList = {}
for _, tableValue in pairs( value ) do
table.insert( resultList, asString( lang, tableValue, options ) )
end
return mw.text.listToText( resultList, options.separator, options.conjunction )
end
---@param entityId string
---@param data source
---@return source
local function populateSourceDataImpl( entityId, data, map )
local wsLink = getSitelink( entityId, 'ruwikisource' )
if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then
data.url = ":ru:s:" .. wsLink
end
populateDataFromEntity( entityId, data, map )
local normativeTitle = getNormativeTitle( entityId )
if normativeTitle then
local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" )
y, m, d = tonumber( y ),tonumber( m ), tonumber( d )
local title = asString( 'ru', data.title, options_commas_nolinks )
local docNumber = getSingle( data.docNumber )
data.title = {
normativeTitle ..
" от " .. tostring( d ) .. " " .. monthGen[ m ] .. " " .. tostring( y ) .. " г." ..
( docNumber and ( " № " .. docNumber ) or '' ) ..
' «' .. title.. '»'
}
end
if not data.title then
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
local label = getLabel( entityId, lang )
if label ~= '' then
data.title = { label }
end
end
return data
end
---@param entityId string
---@param propertyId string
---@param data source
---@return void
local function expandSpecialsQualifiers( entityId, propertyId, data )
local statements = getBestStatements( entityId, propertyId )
for _, statement in pairs( statements ) do
populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP )
end
end
---Expand special types of references when additional data could be found in OTHER entity properties
---@param data source
---@return void
local function expandSpecials( data )
if not data.entityId then
return
end
if data.sourceId == 'Q36578' then
-- Gemeinsame Normdatei -- specified by P227
appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } )
appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } )
data.year = '2012—2016'
expandSpecialsQualifiers( data.entityId, 'P227', data )
elseif data.sourceId == 'Q15222191' then
-- BNF -- specified by P268
appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P268', data )
elseif data.sourceId == 'Q54919' then
-- VIAF -- specified by P214
appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P214', data )
else
-- generic property search
for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do
if sourceClaim.mainsnak.snaktype == 'value' then
local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id
for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do
if sourcePropertyClaim.mainsnak.snaktype == 'value' then
appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', {
format = function( id )
return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' )
end
} )
expandSpecialsQualifiers( data.entityId, sourcePropertyId, data )
break
end
end
end
end
end
-- do we have appropriate record in P1433 ?
local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId )
if claims and #claims ~= 0 then
for _, claim in pairs( claims ) do
populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
end
end
end
---@param text string
---@param tip string
---@return string
local function toTextWithTip( text, tip )
return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>'
end
---@param lang string
---@param placeId string
---@return string
local function getPlaceName( placeId, lang )
-- ГОСТ Р 7.0.12—2011
if lang == 'ru' then
if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end
if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end
if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end
if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end
end
return nil
end
---@param data source
---@param lang string
---@return void
local function preprocessPlace( data, lang )
if not data.place then
return
end
---@type table<number, string>
local newPlace = {}
for index, place in pairs( data.place ) do
if place.id then
local newPlaceStr = getPlaceName( place.id, lang )
if newPlaceStr then
newPlace[ index ] = newPlaceStr
else
newPlace[ index ] = getLabel( place.id, lang )
end
else
newPlace[ index ] = place
end
end
data.place = newPlace
end
---@param entityId string
---@param lang string
---@param providedLabel string | nil
---@param options options
---@return string
local function getPersonNameAsLabel( entityId, lang, providedLabel, options )
-- would custom label provided we don't need to check entity at all
if not isEmpty( providedLabel ) then
return options.format( providedLabel )
end
if lang == 'mul' then
lang = i18nDefaultLanguage
end
---@type string | nil
local personName = getLabel( entityId, lang )
if isEmpty( personName ) then
return '\'\'(not translated to ' .. lang .. ')\'\''
end
if not isInstanceOf( entityId, 'Q5' ) then
return personName
end
return options.format( personName )
end
---@param entityId string
---@param lang string
---@param customLabel string | nil
---@param options options
---@return string
local function getPersonNameAsWikitext( entityId, lang, customLabel, options )
local personName = getPersonNameAsLabel( entityId, lang, customLabel, options )
local link = getElementLink( entityId, lang )
return wrapInUrl( link, personName )
end
---@param value value
---@param lang string
---@param options options
---@return string
local function getPeopleAsWikitext( value, lang, options )
if type( value ) == 'string' then
return options.format( value )
elseif type( value ) == 'table' then
if value.id then
-- this is link
if options.preferids then
return tostring( value.id )
else
if options.nolinks then
return getPersonNameAsLabel( value.id, lang, value.label, options )
else
return getPersonNameAsWikitext( value.id, lang, value.label, options )
end
end
end
local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544)
local resultList = {}
for _, tableValue in pairs( value ) do
local nextWikitext = getPeopleAsWikitext( tableValue, lang, options )
if not isEmpty( nextWikitext ) then
table.insert( resultList, nextWikitext )
if #resultList == maxAuthors + 1 then
-- keep one more to indicate that there are too many
break
end
end
end
local resultWikitext = ''
for i, wikitext in pairs( resultList ) do
if i == maxAuthors + 1 then
resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault )
break
end
if i ~= 1 then
resultWikitext = resultWikitext .. ', '
end
resultWikitext = resultWikitext .. wikitext
end
return resultWikitext
end
return '' -- options.format( '(unknown type)' )
end
---@param lang string
---@param data source
---@return string
local function generateAuthorLinks( lang, data )
local result = ''
if data.author then
result = getPeopleAsWikitext( data.author, lang, options_commas_authors )
result = '<i class="wef_low_priority_links">' .. result .. '</i> '
end
return result
end
---@param lang string
---@param data source
---@param conjunction string
---@param propertyName string
---@param urlPropertyName string?
---@return string
local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName )
if not data[ propertyName ] then
return ''
end
local out
if urlPropertyName and data[ urlPropertyName ] then
out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) )
else
out = asString( lang, data[ propertyName ], options_commas )
end
if not out or out == '' then
return ''
end
return conjunction .. out
end
---@param lang string
---@param data source
---@return string
local function appendTitle( lang, data )
local conjunction = ''
local result = ''
if data.part then
result = result .. appendProperty( lang, data, '', 'part', 'parturl' )
conjunction = ' // '
end
return result .. appendProperty( lang, data, conjunction, 'title', 'url' )
end
---@param lang string
---@return string
local function appendLanguage( lang )
if lang == i18nDefaultLanguage then
return ''
end
---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) }
local langs = require( 'Module:Languages' )
return langs.list_ref( p.currentFrame:newChild{ args = { lang } } )
end
---@param lang string
---@param data source
---@return string
local function appendSubtitle( lang, data )
return appendProperty( lang, data, ': ', 'subtitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendOriginalTitle( lang, data )
return appendProperty( lang, data, ' = ', 'originaltitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublication( lang, data )
if not data.publication then
return ''
end
local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short )
if data.publication.subtitle and data.publication.subtitle ~= '' then
result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short )
end
return result
end
---@param lang string
---@param data source
---@return string
local function appendEditor( lang, data )
if not data.editor and not data.translator then
return ''
end
local result = ' / '
if data.editor then
local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible )
if data.translator then
result = result .. ', '
end
end
if data.translator then
local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible )
end
return result
end
---@param lang string
---@param data source
local function appendEdition( lang, data )
return appendProperty( lang, data, ' — ', 'edition', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublicationData( lang, data )
if not data.place and not data.publisher and not data.year then
return ''
end
local result = ' — '
if data.place then
result = result .. asString( lang, data.place, options_commas_short )
if data.publisher or data.year then
result = result .. ': '
end
end
if data.publisher then
result = result .. asString( lang, data.publisher, options_commas_short )
if data.year then
result = result .. ', '
end
end
if data.year then
result = result .. asString( lang, data.year, options_commas )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendVolumeAndIssue( lang, data )
if not data.volume and not data.issue then
return ''
end
local result = ' — '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.volume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'volume', nil )
result = result ..appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'issue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'issue', nil )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendPages( lang, data )
if not data.pages then
return ''
end
local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ]
local strPages = asString( lang, data.pages, options_commas )
strPages = mw.ustring.gsub( strPages, '[-—]', '—' )
return ' — ' .. letter .. ' ' .. strPages .. '.'
end
---@param lang string
---@param data source
---@return string
local function appendNumberOfPages( lang, data )
if not data.numberOfPages then
return ''
end
local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ]
return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. ' ' .. letter
end
---@param lang string
---@param data source
---@return string
local function appendBookSeries( lang, data )
if not data.bookSeries then
return ''
end
local result = appendProperty( lang, data, ' — (', 'bookSeries', nil )
if data.bookSeriesVolume or data.bookSeriesIssue then
result = result .. '; '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.bookSeriesVolume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'bookSeriesVolume', nil )
result = result .. appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'bookSeriesIssue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'bookSeriesIssue', nil )
end
end
result = result .. ')'
return result
end
---@param lang string
---@param data source
---@return string
local function appendTirage( lang, data )
if not data.tirage then
return ''
end
local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ]
---@type options
local optionsTirage = {
separator = '; ',
conjunction = '; ',
format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end,
short = false,
nolinks = false,
preferids = false,
}
return ' — ' .. asString( lang, data.tirage, optionsTirage )
end
---@param lang string
---@param value string | nil
---@param options options
---@param prefix string?
---@return string
local function appendIdentifier( lang, value, options, prefix )
if not value then
return ''
end
return ' — ' .. ( prefix or '' ) .. asString( lang, value, options )
end
---@param result string
---@param lang string
---@param data source
---@return string
local function wrapSourceId( result, lang, data )
if not data.sourceId then
return result
end
local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown'
return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>'
end
---@param data source
---@return string
local function appendAccessDate( data )
if not data.accessdate then
return ''
end
local date = getSingle( data.accessdate )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local y, m, d = mw.ustring.match( date, pattern )
y, m, d = tonumber( y ), tonumber( m ), tonumber( d )
local date_str = ( d > 0 and ' ' .. tostring( d ) or '' )
.. ( m > 0 and ' ' .. monthGen[ m ] or '' )
.. ( y > 0 and ' ' .. tostring( y ) or '' )
return " <small>Проверено" .. date_str .. ".</small>"
end
---@param data source
---@param lang string
---@return void
local function populateUrl( data, lang )
if data.sourceId and not data.url then
local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' )
if sitelink then
data.url = ':' .. lang .. ':s:' .. sitelink
end
end
end
---@param data source
---@return void
local function populateYear( data )
if not data.year and data.dateOfPublication then
local date = getSingle( data.dateOfPublication )
data.year = mw.ustring.sub( date, 2, 5 )
end
if not data.year and data.dateOfCreation then
local date = getSingle( data.dateOfCreation )
data.year = mw.ustring.sub( date, 2, 5 )
end
end
---@param data source
---@return void
local function populateTitle( data )
data.title = data.title or getSingle( data.url )
end
---@param data source
---@return string
local function renderSource( data )
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
preprocessPlace( data, lang )
populateUrl( data, lang )
populateTitle( data )
if not data.title then
return ''
end
populateYear( data )
local result = generateAuthorLinks( lang, data )
result = result .. appendTitle( lang, data )
result = result .. appendLanguage( lang )
result = result .. appendSubtitle( lang, data )
result = result .. appendOriginalTitle( lang, data )
result = result .. appendPublication( lang, data )
result = result .. '<span class="wef_low_priority_links">'
result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution
result = result .. appendEdition( lang, data )
result = result .. appendPublicationData( lang, data )
result = result .. appendVolumeAndIssue( lang, data )
result = result .. appendPages( lang, data )
result = result .. appendNumberOfPages( lang, data )
result = result .. appendBookSeries( lang, data )
result = result .. appendTirage( lang, data )
result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' )
result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' )
result = result .. appendIdentifier( lang, data.doi, options_doi, nil )
result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil )
result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil )
result = result .. appendAccessDate( data )
result = result .. '</span>'
return wrapSourceId( result, lang, data )
end
---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания
---@param snaks snaks
---@return string | nil
local function renderReferenceImpl( data, snaks )
-- не показывать источники с "импортировано из"
if snaks.P143 then
return nil
end
-- забрать данные из reference
populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
expandSpecials( data )
populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP )
expandPublication( data )
expandBookSeries( data )
if next( data ) == nil then
return nil
end
local rendered = renderSource( data )
if mw.ustring.len( rendered ) == 0 then
return nil
end
if data.ref then
local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' )
rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>'
end
return rendered
end
---@param frame frame
---@param currentEntityId string | { id: string }
---@param reference table{ snaks: snaks }
---@return string | nil
function p.renderSource( frame, currentEntityId, reference )
reference = reference or { snaks = {} }
p.currentFrame = frame
local data = getFilledArgs( frame.args or {} )
populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
if not currentEntityId then
data.entityId = mw.wikibase.getEntityIdForCurrentPage()
elseif type( currentEntityId ) == 'string' then
data.entityId = currentEntityId
elseif type( currentEntityId ) == 'table' and currentEntityId.id then
data.entityId = currentEntityId.id
end
---@type string
local rendered = renderReferenceImpl( data, reference.snaks or {} )
if not rendered then
return ''
end
return rendered
end
---@param frame frame
---@param currentEntityId string
---@param reference table
---@return string
function p.renderReference( frame, currentEntityId, reference )
local rendered = p.renderSource( frame, currentEntityId, reference )
if not rendered or rendered == '' then
return ''
end
-- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет
-- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши.
return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]'
end
---@param frame frame
---@return string | nil
function p.testPersonNameToAuthorName( frame )
return personNameToAuthorName( frame.args[ 1 ] )
end
---@param frame frame
---@return string | nil
function p.testPersonNameToResponsibleName( frame )
return personNameToResponsibleName( frame.args[ 1 ] )
end
return p
752a204827a41ecd6cf518bdb22da12718bca2ec
Модуль:Message box/ombox.css
828
73
156
2024-06-21T16:47:35Z
wikipedia, ruwikipedia>Putnik
0
исправление цвета рамки
text
text/plain
/* Скопировано из [[:en:Module:Message box/ombox.css]] */
.ombox {
margin: 4px 0;
border-collapse: collapse;
border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */
background-color: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
}
/* For the "small=yes" option. */
.ombox.mbox-small {
font-size: 88%;
line-height: 1.25em;
}
.ombox-speedy {
border: 2px solid var(--border-color-error, #b32424); /* Red */
background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */
}
.ombox-delete {
border: 2px solid var(--background-color-error--active, #b32424); /* Red */
}
.ombox-content {
border: 1px solid #f28500; /* Orange */
}
.ombox-style {
border: 1px solid #fc3; /* Yellow */
}
.ombox-move {
border: 1px solid #9932cc; /* Purple */
}
.ombox-protection {
border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */
}
.ombox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.ombox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.ombox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ombox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
.ombox .mbox-invalid-type {
text-align: center;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.ombox .mbox-textsmall-div {
font-size: 90%;
}
@media (min-width: 720px) {
.ombox {
margin: 4px 10%;
}
.ombox.mbox-small {
/* @noflip */
clear: right;
/* @noflip */
float: right;
/* @noflip */
margin: 4px 0 4px 1em;
width: 238px;
}
/* Стили нотификаций для ноутбуков */
@media (max-width: 1366px) {
.ombox {
margin-left: 6%;
margin-right: 6%;
}
}
}
/* [[Категория:Модули:Подстраницы CSS]] */
6627874170f6674674bfa5796b2f7dfb6698cd81
Шаблон:Doc/begin
10
54
118
2024-06-30T22:14:58Z
wikipedia, ruwikipedia>Putnik
0
[[ВП:×|отмена]] правки 138443392 участника [[Special:Contribs/Putnik|Putnik]] ([[UT:Putnik|обс.]])
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Doc/styles.css" />
<div class="ts-doc-doc" id="doc">
<div class="ts-doc-header" id="Документация">
<div class="ts-doc-heading">Документация</div>
{{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }}
</div>
<div class="ts-doc-content"></includeonly><noinclude>
{{doc}}
</noinclude>
c753f0a9f65d86707cdffaf93fb49c2c52daf92b
Модуль:Navbar
828
63
136
2024-07-08T20:00:10Z
wikipedia, ruwikipedia>Putnik
0
более контрастная серая иконка шестерёнки в тёмной теме
Scribunto
text/plain
local p = {}
local hlist = 'Template:Flatlist/styles.css'
local templatestyles = 'Module:Navbar/styles.css'
local getArgs
function p._ruwikiNavbar( args )
local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local whiteColorDefs = {
['#fff'] = true,
['#ffffff'] = true,
['white'] = true,
}
local fontColor = args.fontcolor and args.fontcolor:lower()
local isWhite = fontColor and whiteColorDefs[ fontColor ] == true
local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() )
if not isWhite and fontStyle then
local styleratio = require( 'Module:Color contrast' )._styleratio
isWhite = styleratio( {
fontStyle .. '; color:#666;',
'',
'#666'
} ) < 3.66
end
local isTemplate = title.namespace == 10
local altText = string.format(
'Перейти %s «%s»',
isTemplate and 'к шаблону' or 'на страницу',
mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ]
)
return string.format(
'[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]',
isWhite and ' white' or '',
isWhite and '' or ' skin-invert-image',
tostring( title ),
altText
)
end
function p.ruwikiNavbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._ruwikiNavbar(getArgs(frame))
end
function p._navbar(args)
local titleArg = 1
if args.collapsible then
titleArg = 2
if not args.plain then
args.mini = 1
end
if args.fontcolor then
args.fontstyle = 'color:' .. args.fontcolor .. ';'
end
args.style = 'float:left; text-align:left; white-space:nowrap;'
end
if args[titleArg] == 'off' then
return
end
local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or '';
local tag
if args.nodiv then
tag = 'span'
else
tag = 'div'
end
local div = mw.html.create():tag(tag)
div
:addClass('navbar hlist plainlinks noprint')
:attr('data-navboxnavigation-link', '0')
:cssText(args.style)
if args.mini then div:addClass('navbar-mini') end
if not (args.mini or args.plain) then
div
:tag('span')
:addClass('navbar-boxtext')
:cssText(args.fontstyle)
:wikitext(args.text or 'Шаблон:')
:wikitext(' ')
end
local ul = div:tag('ul');
if args.brackets then
ul:addClass('navbar-brackets')
end
ul
:tag('li')
:addClass('nv-view')
:wikitext('[[' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:addClass(args.mini and 'navbar-mini-abbr')
:attr('title', 'Просмотр этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'п' or 'просмотр')
:done()
:wikitext(']]')
:done()
:tag('li')
:addClass('nv-talk')
:wikitext('[[' .. talkpage .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Обсуждение этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'о' or 'обсуждение')
:done()
:wikitext(']]');
if not args.noedit then
ul
:tag('li')
:addClass('nv-edit')
:wikitext('[[Special:EditPage/' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Править этот шаблон')
:cssText(args.fontstyle)
:wikitext(args.mini and 'р' or 'править')
:done()
:wikitext(']]');
end
if args.collapsible then
div:done()
:tag('span')
:addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' )
:cssText(args.fontstyle)
:wikitext(args[1])
end
local frame = mw.getCurrentFrame()
return frame:extensionTag{
name = 'templatestyles', args = { src = hlist }
} .. frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
} .. tostring(div:done())
end
function p.navbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._navbar(getArgs(frame))
end
return p
695777e4dafbd5f7bf8b4f35d8db9349d08a363d
Шаблон:Doc/styles.css
10
55
120
2024-08-05T07:09:06Z
wikipedia, ruwikipedia>Putnik
0
исправление кода для тёмной темы ([[phab:T369874]])
text
text/plain
.ts-doc-doc {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
clear: both;
margin-top: 1em;
}
/* Ctrl+F ":target" in [[MediaWiki:Common.css]] */
.ts-doc-doc sup.reference:target,
.ts-doc-doc ol.references li:target,
.ts-doc-doc .highlight-target:target,
.ts-doc-doc cite:target,
.ts-doc-doc span.citation:target {
background: var(--ruwiki-background-color-blue200, #cfe3ff);
}
.ts-doc-header {
align-items: center;
background: var(--ruwiki-background-color-blue200, #cfe3ff);
display: flex;
flex-wrap: wrap;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
margin-left: auto;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 2em;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat;
background-size: contain;
font-size: small;
min-height: 1.75em;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media screen {
html.skin-theme-clientpref-night .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header {
display: block;
}
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
be8d912472a37a6051bee114da86f913839e7ca0
Модуль:Message box/configuration
828
18
46
2024-08-29T15:57:44Z
wikipedia, ruwikipedia>Putnik
0
замена notheme на стили тёмной темы для cmbox
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]',
templatestyles = 'Module:Message box/ambox.css',
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/cmbox.css',
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/fmbox.css',
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов',
templatestyles = 'Module:Message box/imbox.css',
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/ombox.css',
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений',
templatestyles = 'Module:Message box/tmbox.css',
}
}
2c0750ec1561e8ec25c0988c411f3c69e4957483
Шаблон:Государство/doc
10
104
218
2024-09-11T09:57:25Z
wikipedia, ruwikipedia>A1788
0
wikitext
text/x-wiki
{{docpage}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах;
* для исторических государств используйте {{t|историческое государство}}.
* для составных частей государств используйте {{t|Административная единица}}.
== Образец для копирования ==
<pre>
{{Государство
|Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять -->
|Русское название =
|Оригинальное название =
|Родительный падеж =
|Герб =
|Вместо герба =
|Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва -->
|Перевод девиза =
|Название гимна =
|Перевод названия гимна =
|Аудио =
|Форма правления =
|Государственный строй =
|Государственная религия =
|На карте =
|подпись к карте =
|На карте2 =
|Язык/Языки =
|Основано/Основана =
|Дата/Даты независимости =
|Независимость от =
|Столица =
|Крупнейшие города =
|Должность руководителя 1 =
|Руководитель 1 =
|Должность руководителя 2 =
|Руководитель 2 =
|Должность руководителя 3 =
|Руководитель 3 =
|Должность руководителя 4 =
|Руководитель 4 =
|Должность руководителя 5 =
|Руководитель 5 =
|Место по территории =
|Территория =
|Процент воды =
|Этнохороним =
|Место по населению =
|Население =
|Год оценки =
|Население по переписи =
|Год переписи =
|Плотность населения =
|Место по плотности =
|ВВП (ППС) =
|Год расчёта ВВП (ППС) =
|Место по ВВП (ППС) =
|ВВП (ППС) на душу населения =
|Место по ВВП (ППС) на душу населения =
|ВВП (номинал) =
|Год расчёта ВВП (номинал) =
|Место по ВВП (номинал) =
|ВВП (номинал) на душу населения =
|Место по ВВП (номинал) на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта =
|Домен/Домены =
|Телефонный код =
|Часовой пояс =
|Автомобильное движение =
|Примечания =
<!-- |Без флага и герба=* -->
<!-- |Без гимна=* -->
}}
</pre>
== Описание параметров ==
Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]] —
<pre> |Язык = [[Албанский язык|албанский]]</pre>
а в статье [[Канада]] —
<pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre>
Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»:
<pre>
|Спорный статус = да
|Основано =
|Основана =
|Дата образования =
|Провозглашение независимости =
|Дипломатическое признание =
|Независимость от =
</pre>
Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус = непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]].
== Пример использования ==
{{demo|reverse=1|br=|<nowiki>{{Государство
|Русское название = Финляндская Республика
|Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}}
|Родительный падеж = Финляндии
|Герб = Coat of arms of Finland.svg
|Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} -->
|Вместо герба =
|Девиз =
|Перевод девиза =
|Название гимна = Maamme
|Перевод названия гимна = Наш край
|Аудио =
|Форма правления = [[президентская республика]]
|Государственный строй = [[унитарное государство]]
|Государственная религия =
|На карте = EU-Finland.svg
|подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный)
|На карте2 =
|Языки = [[финский язык|финский]], [[шведский язык|шведский]]
|Основано/Основана =
|Дата независимости = [[6 декабря]] [[1917]]
|Независимость от = [[Россия|России]]
|Столица = [[Хельсинки]]
|Крупнейший город = Хельсинки
|Должность руководителя 1 = [[Президент Финляндии|Президент]]
|Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]]
|Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]]
|Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]]
|Место по территории = 63
|Территория = 338 145
|Процент воды = 9,96
|Этнохороним = финляндец, финляндка
|Место по населению = 106
|Население = 5 219 732
|Год оценки = 2003
|Население по переписи =
|Год переписи =
|Плотность населения = 15,4
|Место по плотности =
|ВВП =
|Год расчёта ВВП =
|Место по ВВП =
|ВВП на душу населения =
|Место по ВВП на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref>
|Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]])
|Телефонный код = 358
|Часовой пояс = +2
|Автомобильное движение =
|Примечания = <references/>
}}</nowiki>}}
== TemplateData ==
<templatedata>
{
"params": {
"Спорный статус": {},
"Статус": {},
"Русское название": {},
"Оригинальное название": {},
"Флаг": {
"type": "wiki-file-name"
},
"Ссылка на флаг": {},
"Родительный падеж": {},
"Герб": {
"type": "wiki-file-name"
},
"Отображаемая подпись герба": {},
"Вместо герба": {},
"Девиз": {},
"Перевод девиза": {},
"Без гимна": {},
"Название гимна": {},
"Перевод названия гимна": {},
"Аудио": {},
"На карте": {},
"На карте2": {},
"Дата1": {},
"Дата2": {},
"Дата3": {},
"Дата4": {},
"Дата5": {},
"Дата6": {},
"Дата7": {},
"Дата8": {},
"Дата9": {},
"Дата10": {},
"Дата11": {},
"Дата12": {},
"sovereignty_type": {},
"Этап1": {},
"Этап2": {},
"Этап3": {},
"Этап4": {},
"Этап5": {},
"Этап6": {},
"Этап7": {},
"Этап8": {},
"Этап9": {},
"Этап10": {},
"Этап11": {},
"Этап12": {},
"Основана": {},
"Основано": {},
"Дата образования": {},
"Провозглашение независимости": {},
"Независимость от": {},
"Дипломатическое признание": {},
"Отображаемый тип независимости": {},
"Даты независимости": {},
"Дата независимости": {},
"Язык": {},
"Языки": {},
"Столица": {},
"Крупнейший город": {},
"Крупнейшие города": {},
"Форма правления": {},
"Должность руководителя 1": {},
"Должности руководителей": {},
"Руководитель 1": {},
"Руководители": {},
"Должность руководителя 2": {},
"Руководитель 2": {},
"Должность руководителя 3": {},
"Руководитель 3": {},
"Должность руководителя 4": {},
"Руководитель 4": {},
"Должность руководителя 5": {},
"Руководитель 5": {},
"Государственная религия": {},
"Место по территории": {},
"Территория": {},
"Процент воды": {},
"Территория2": {},
"Население": {},
"Год оценки": {},
"Год переписи": {},
"Население2": {},
"Место по населению": {},
"Население по переписи": {},
"Плотность населения": {},
"Место по плотности": {},
"ВВП": {},
"Год расчёта ВВП": {},
"Место по ВВП": {},
"ВВП на душу населения": {},
"Место по ВВП на душу населения": {},
"ВВП (ППС)": {},
"Год расчёта ВВП (ППС)": {},
"Место по ВВП (ППС)": {},
"ВВП (ППС) на душу населения": {},
"Место по ВВП (ППС) на душу населения": {},
"ВВП (номинал)": {},
"Год расчёта ВВП (номинал)": {},
"Место по ВВП (номинал)": {},
"ВВП (номинал) на душу населения": {},
"Место по ВВП (номинал) на душу населения": {},
"Год расчёта ИРЧП": {},
"ИРЧП": {},
"Уровень ИРЧП": {},
"Место по ИРЧП": {},
"Этнохороним": {},
"Валюта": {},
"Домены": {},
"Домен": {},
"Телефонный код": {},
"Часовые пояса": {},
"Часовой пояс": {},
"Примечания": {},
"nocat": {
"type": "boolean"
},
"lat_deg": {},
"lat_min": {},
"lat_sec": {},
"lat_dir": {},
"lon_deg": {},
"lon_min": {},
"lon_sec": {},
"lon_dir": {},
"region": {},
"CoordScale": {},
"Размер герба": {
"aliases": [
"размер герба"
],
"type": "number"
},
"Размер флага": {
"aliases": [
"размер флага"
],
"type": "number"
},
"Размер карты": {
"aliases": [
"размер карты"
]
},
"Подпись к карте": {
"aliases": [
"подпись к карте"
]
},
"Размер карты2": {
"aliases": [
"размер карты2"
]
},
"Государственный строй": {},
"Автомобильное движение": {}
},
"paramOrder": [
"Статус",
"Спорный статус",
"Русское название",
"Оригинальное название",
"Флаг",
"Размер флага",
"Ссылка на флаг",
"Родительный падеж",
"Герб",
"Размер герба",
"Отображаемая подпись герба",
"Вместо герба",
"Девиз",
"Перевод девиза",
"Без гимна",
"Название гимна",
"Перевод названия гимна",
"Аудио",
"На карте",
"Размер карты",
"Подпись к карте",
"На карте2",
"Размер карты2",
"Дата1",
"Дата2",
"Дата3",
"Дата4",
"Дата5",
"Дата6",
"Дата7",
"Дата8",
"Дата9",
"Дата10",
"Дата11",
"Дата12",
"sovereignty_type",
"Этап1",
"Этап2",
"Этап3",
"Этап4",
"Этап5",
"Этап6",
"Этап7",
"Этап8",
"Этап9",
"Этап10",
"Этап11",
"Этап12",
"Основана",
"Основано",
"Дата образования",
"Провозглашение независимости",
"Независимость от",
"Дипломатическое признание",
"Отображаемый тип независимости",
"Даты независимости",
"Дата независимости",
"Язык",
"Языки",
"Столица",
"Крупнейший город",
"Крупнейшие города",
"Форма правления",
"Государственный строй",
"Должность руководителя 1",
"Должности руководителей",
"Руководитель 1",
"Руководители",
"Должность руководителя 2",
"Руководитель 2",
"Должность руководителя 3",
"Руководитель 3",
"Должность руководителя 4",
"Руководитель 4",
"Должность руководителя 5",
"Руководитель 5",
"Государственная религия",
"Место по территории",
"Территория",
"Процент воды",
"Территория2",
"Население",
"Год оценки",
"Год переписи",
"Население2",
"Место по населению",
"Население по переписи",
"Плотность населения",
"Место по плотности",
"ВВП",
"Год расчёта ВВП",
"Место по ВВП",
"ВВП на душу населения",
"Место по ВВП на душу населения",
"ВВП (ППС)",
"Год расчёта ВВП (ППС)",
"Место по ВВП (ППС)",
"ВВП (ППС) на душу населения",
"Место по ВВП (ППС) на душу населения",
"ВВП (номинал)",
"Год расчёта ВВП (номинал)",
"Место по ВВП (номинал)",
"ВВП (номинал) на душу населения",
"Место по ВВП (номинал) на душу населения",
"Год расчёта ИРЧП",
"ИРЧП",
"Уровень ИРЧП",
"Место по ИРЧП",
"Этнохороним",
"Валюта",
"Домены",
"Домен",
"Телефонный код",
"Часовые пояса",
"Часовой пояс",
"Автомобильное движение",
"Примечания",
"lat_deg",
"lat_min",
"lat_sec",
"lat_dir",
"lon_deg",
"lon_min",
"lon_sec",
"lon_dir",
"region",
"CoordScale",
"nocat"
],
"format": "block"
}
</templatedata>
== См. также ==
* {{tl|Историческое государство}}
<includeonly>
[[Категория:Шаблоны-карточки:Географические объекты]]
</includeonly>
b1e2b1107db0671d3bcc4dda5bd29020192c442e
Шаблон:Docpage
10
60
130
2024-09-25T09:40:06Z
wikipedia, ruwikipedia>Stjn
0
__EXPECTED_UNCONNECTED_PAGE__
wikitext
text/x-wiki
<includeonly>{{#ifeq: {{SUBPAGENAME}} | doc
| {{fmbox
| class = hlist nowraplinks
| style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff);
| image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]]
| text = <div>
* [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]]
* [[:{{SUBJECTPAGENAME}}|Документация]]
* [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]]
* [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} |
** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}}
}}</div><!--
-->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }}
}}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Категория:Модули:Документация]]
| [[Категория:Шаблоны:Документация]]
}}__EXPECTED_UNCONNECTED_PAGE__
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
e2d07566c50be35ac409e8396893a3b9d8676e0c
Шаблон:Карточка/styles.css
10
105
220
2024-10-01T01:43:01Z
wikipedia, ruwikipedia>Stjn
0
перенос стилей из [[шаблон:Карточка/флаг и герб]]
text
text/plain
/* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */
/* [[Шаблон:Карточка/флаг и герб]] */
.ts-infobox-flaginfo {
background: none;
border-collapse: collapse;
display: table;
text-align: center;
width: 100%;
}
.ts-infobox-flaginfo td {
vertical-align: middle;
}
body.skin--responsive.skin-minerva.skin-minerva .ts-infobox-flaginfo td {
/* Минерва требует хаков, чтобы эти стили работали */
border-bottom: 0;
vertical-align: middle;
}
/* Таблицы */
.infobox-table,
.infobox-tablebox {
padding: 0;
}
.infobox-inner-table,
.infobox-table > table,
.infobox-tablebox > table {
width: 100%;
display: table;
margin: 0;
background: transparent;
}
.infobox-tablebox > table {
border: 1px solid var(--border-color-base, #a2a9b1);
border-collapse: separate;
}
/* Встраиваемая карточка */
.infobox-child {
width: 100%;
margin: 0;
padding: 0;
border: none;
font-size: 100%;
}
body.skin-minerva table.infobox-child {
width: 100% !important;
margin: 0 !important;
padding: 0;
border: none;
font-size: 100%;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
25901ad6113ef3908fc70305ce64eb64925c665f
Шаблон:Карточка/флаг и герб
10
98
206
2024-10-24T14:21:28Z
wikipedia, ruwikipedia>Putnik
0
fix
wikitext
text/x-wiki
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<templatestyles src="Шаблон:Карточка/styles.css" /><table role="presentation" class="ts-infobox-flaginfo">
<tr>
{{if-wikidata|p41|{{{флаг|}}}|<td>{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|<td>{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}}
</tr>
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr>
{{if-wikidata|p41|{{{флаг|}}}|3=<td class="media-caption">{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|3=<td class="media-caption">{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}}
</tr>}}</table>
}}<noinclude>
{{doc}}
</noinclude>
1790949866597b0909572cd51fdfb8b9a7db55ff
Модуль:Wikidata
828
82
174
2024-10-26T15:17:47Z
wikipedia, ruwikipedia>Stjn
0
[[ВП:×|отмена]]: сломало отображение в множестве статей
Scribunto
text/plain
---settings, may differ from project to project
local fileDefaultSize = '267x400px'
local outputReferences = true
local writingSystemElementId = 'Q8209'
local langElementId = 'Q7737'
---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании)
local moduleSources = require( 'Module:Sources' )
local WDS = require( 'Module:WikidataSelectors' )
---Константы
---@type string
local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode()
local p = {}
local g_config, g_frame
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement,
formatStatementDefault, getSourcingCircumstances, getPropertyParams
---@param obj table
---@param target table
---@param skipEmpty boolean | nil
---@return table
local function copyTo( obj, target, skipEmpty )
for key, val in pairs( obj ) do
if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then
target[ key ] = val
end
end
return target
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function min( prev, next )
if prev == nil or prev > next then
return next
end
return prev
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function max( prev, next )
if prev == nil or prev < next then
return next
end
return prev
end
---@param section string
---@param code string
---@return any | nil
local function getConfig( section, code )
if g_config == nil then
g_config = require( 'Module:Wikidata/config' )
end
if not g_config then
g_config = {}
end
if not section then
return g_config
end
if not code then
return g_config[ section ] or {}
end
if not g_config[ section ] then
return nil
end
return g_config[ section ][ code ]
end
---@param code string
---@param sortKey string | nil
---@return string
local function getCategoryByCode( code, sortKey )
local value = getConfig( 'categories', code )
if not value or value == '' then
return ''
end
if sortKey ~= nil then
return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать?
else
return '[[Category:' .. value .. ']]'
end
end
---@param isoStr string | table
---@return table | nil
local function splitISO8601( isoStr )
if 'table' == type( isoStr ) then
if isoStr.args and isoStr.args[ 1 ] then
isoStr = '' .. isoStr.args[ 1 ]
else
return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr )
end
end
local Y, M, D = ( function( str )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local _Y, _M, _D = mw.ustring.match( str, pattern )
return tonumber( _Y ), tonumber( _M ), tonumber( _D )
end )( isoStr )
local h, m, s = ( function( str )
local pattern = "T(%d+):(%d+):(%d+)%Z"
local _H, _M, _S = mw.ustring.match( str, pattern )
return tonumber( _H ), tonumber( _M ), tonumber( _S )
end )( isoStr )
local oh, om = ( function( str )
if str:sub(-1) == "Z" then -- ends with Z, Zulu time
return 0, 0
end
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern )
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber( sign .. oh ), tonumber( sign .. om )
end )( isoStr )
return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s }
end
---Внутренняя функции для получения границ временного диапазона
---@param time string
---@param precision number
---@return table | nil
function p._parseTimeBoundaries( time, precision )
local s = splitISO8601( time )
if not s then
return nil
end
if precision >= 0 and precision <= 8 then
local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }
local power = powers[ precision + 1 ]
local left = s.year - ( s.year % power )
return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 9 then
return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 }
end
if precision == 10 then
local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local lastDay = lastDays[ s.month ]
return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 11 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 12 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 13 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 14 then
local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) )
return { t * 1000, t * 1000 + 999 }
end
error( 'Unsupported precision: ' .. precision )
end
---Внутренняя функция для получения числового значения времени из snak'а
---@param table snak
---@return number | nil
function p._parseTimeFromSnak( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then
local timeData = splitISO8601( tostring( snak.datavalue.value.time ) )
timeData.month = math.max( timeData.month, 1 )
timeData.day = math.max( timeData.day, 1 )
return tonumber( os.time( timeData ) ) * 1000
end
return nil
end
---Функция для формирования категории на основе wikidata/config
---@param options table
---@param entityId string
---@return string
local function extractCategory( options, entityId )
if not entityId or not options.category or options.nocat then
return ''
end
if type( entityId ) ~= 'string' then
entityId = entityId.id
end
local claims = WDS.load( entityId, options.category )
if not claims then
return ''
end
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'wikibase-entityid'
then
local catEntityId = claim.mainsnak.datavalue.value.id
local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId )
if wbStatus and catSiteLink then
return '[[' .. catSiteLink .. ']]'
end
end
end
return ''
end
---Преобразует строку в булевое значение
---@param valueToParse string
---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях
local function toBoolean( valueToParse, defaultValue )
if valueToParse ~= nil then
if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then
return false
end
return true
end
return defaultValue
end
---Обрачивает отформатированное значение в инлайновый или блочный тег.
---@param value string value
---@param attributes table of attributes
---@return string HTML tag with value
local function wrapValue( value, attributes )
local tagName = 'span'
local spacer = ''
if string.match( value, '\n' )
or string.match( value, '<t[dhr][ >]' )
or string.match( value, '<div[ >]' )
or string.find( value, 'UNIQ%-%-imagemap' )
then
tagName = 'div'
spacer = '\n'
end
local attrString = ''
for key, val in pairs( attributes or {} ) do
local _key = mw.text.trim( key )
local _value = mw.text.encode( mw.text.trim( val ) )
attrString = attrString .. _key .. '="' .. _value .. '" '
end
return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>'
end
---Wraps formatted snak value into HTML tag with attributes.
---@param value string value of snak
---@param hash string
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapSnak( value, hash, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak'
if hash then
newAttributes[ 'data-wikidata-hash'] = hash
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted statement value into HTML tag with attributes.
---@param value string value of statement
---@param propertyId string PID of property
---@param claimId string ID of claim or nil for local value
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapStatement( value, propertyId, claimId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = newAttributes[ 'class' ] or ''
newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId )
if claimId then
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim'
newAttributes[ 'data-wikidata-claim-id' ] = claimId
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted qualifier's statement value into HTML tag with attributes.
---@param value string value of qualifier's statement
---@param qualifierId string PID of qualifier
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapQualifier( value, qualifierId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId )
return wrapValue( value, newAttributes )
end
---Функция для получения сущности (еntity) для текущей страницы
---Подробнее о сущностях см. d:Wikidata:Glossary/ru
---@param id string Идентификатор (типа P18, Q42)
---@return table Таблица, элементы которой индексируются с нуля
local function getEntityFromId( id )
local entity
local wbStatus
if id then
wbStatus, entity = pcall( mw.wikibase.getEntity, id )
else
wbStatus, entity = pcall( mw.wikibase.getEntity )
end
return entity
end
---Внутренняя функция для формирования сообщения об ошибке
---@param key string Ключ элемента в таблице config.errors (например entity-not-found)
---@return void
local function throwError( key )
error( getConfig( 'errors', key ) )
end
---Функция для получения идентификатора сущностей
---@param value table
---@return string
local function getEntityIdFromValue( value )
local prefix = ''
if value[ 'entity-type' ] == 'item' then
prefix = 'Q'
elseif value[ 'entity-type' ] == 'property' then
prefix = 'P'
else
throwError( 'unknown-entity-type' )
end
return prefix .. value[ 'numeric-id' ]
end
---Проверка на наличие специализированной функции в опциях
---@param options table
---@param prefix string
---@return function
local function getUserFunction( options, prefix, defaultFunction )
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then
-- проверка на пустые строки в параметрах или их отсутствие
if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then
throwError( 'unknown-' .. prefix .. '-module' )
end
-- динамическая загруза модуля с обработчиком указанным в параметре
local formatter = require( 'Module:' .. options[ prefix .. '-module' ] )
if formatter == nil then
throwError( prefix .. '-module-not-found' )
end
local fun = formatter[ options[ prefix .. '-function' ] ]
if fun == nil then
throwError( prefix .. '-function-not-found' )
end
return fun
end
return defaultFunction
end
---Выбирает свойства по property id, дополнительно фильтруя их по рангу
---@param context table
---@param options table
---@param propertySelector string
---@return table | nil
local function selectClaims( context, options, propertySelector )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entity is missing' ); end
if not propertySelector then error( 'propertySelector not specified' ); end
local result = WDS.load( options.entityId, propertySelector )
if not result or #result == 0 then
return nil
end
if options.limit and options.limit ~= '' and options.limit ~= '-' then
local limit = tonumber( options.limit, 10 )
while #result > limit do
table.remove( result )
end
end
return result
end
---Функция для получения значения свойства элемента в заданный момент времени.
---@param entityId string
---@param boundaries table Временные границы
---@param propertyIds table<string>
---@param selectors table<string>
---@return table Таблица соответствующих значений свойства
local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end
local results = {}
if not propertyIds or #propertyIds == 0 then
return results
end
for i, propertyId in ipairs( propertyIds ) do
local selector
if selectors ~= nil then
selector = selectors[ i ] or selectors[ propertyId ] or propertyId
else
selector = propertyId
end
local fakeAllClaims = {}
fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' )
if filteredClaims then
for _, claim in pairs( filteredClaims ) do
if not boundaries then
if not claim.qualifiers or not claim.qualifiers.P582 then
table.insert( results, claim.mainsnak )
end
else
local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' )
local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' )
if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and
( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] )
then
table.insert( results, claim.mainsnak )
end
end
end
end
if #results > 0 then
break
end
end
return results
end
---@param context table
---@param propertyId string
---@return table | nil
function p.getTimeBoundariesFromProperty( context, propertyId )
local dateClaims = WDS.filter( context.entity.claims, propertyId )
if not dateClaims or #dateClaims == 0 then
return nil;
end
-- only support exact date so far, but need improvment
local left = nil
local right = nil
for _, claim in pairs( dateClaims ) do
if not claim.mainsnak then
return nil
end
local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
if not left or not right then
return nil
end
return { left, right }
end
---@param context table
---@param propertyIds table<string>
---@return table | nil
function p.getTimeBoundariesFromProperties( context, propertyIds )
for _, propertyId in ipairs( propertyIds ) do
local result = p.getTimeBoundariesFromProperty( context, propertyId );
if result then
return result
end
end
return nil
end
---@param context table
---@param statement table
---@param qualifierId string
---@return table | nil
function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
-- only support exact date so far, but need improvement
local left, right
if statement.qualifiers and statement.qualifiers[ qualifierId ] then
for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do
local boundaries = context.parseTimeBoundariesFromSnak( qualifier )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
end
if not left or not right then
return nil
end
return { left, right }
end
---@param _ table
---@param context table
---@param statement table
---@param qualifierIds table<string>
---@return table | nil
function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds )
if not qualifierIds then
qualifierIds = { 'P582', 'P580', 'P585' }
end
for _, qualifierId in pairs( qualifierIds ) do
local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
if result then
return result
end
end
return nil
end
---@type table<string>
local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' }
---@type table<string>
local getLabelWithLang_DEFAULT_SELECTORS = {
'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]'
}
---Функция для получения метки элемента в заданный момент времени.
---@param context table
---@param options table
---@param entityId string
---@param boundaries table
---@param propertyIds table
---@param selectors table<string>
---@return string, string Текстовая метка элемента, язык метки
local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end
if not entityId then
return nil
end
local langCode = CONTENT_LANGUAGE_CODE
-- name from label
local label
if options.text and options.text ~= '' then
label = options.text
else
if not propertyIds then
propertyIds = getLabelWithLang_DEFAULT_PROPERTIES
selectors = getLabelWithLang_DEFAULT_SELECTORS
end
-- name from properties
local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
for _, result in pairs( results ) do
if result.datavalue and result.datavalue.value then
if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then
label = result.datavalue.value.text
langCode = result.datavalue.value.language
break
elseif result.datavalue.type == 'string' then
label = result.datavalue.value
break
end
end
end
if not label then
label, langCode = mw.wikibase.getLabelWithLang( entityId )
if not langCode then
return nil
end
end
end
return label, langCode
end
---@param context table
---@param options table
---@return string
local function formatPropertyDefault( context, options )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
local claims
if options.property then -- TODO: Почему тут может не быть property?
if options.rank then -- передать настройки ранга из конфига
claims = context.selectClaims( options, options.property .. options.rank )
else
claims = context.selectClaims( options, options.property )
end
end
if claims == nil then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных
-- заявлений в таблице
local formattedClaims = {}
for _, claim in pairs( claims ) do
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
if formattedStatement and formattedStatement ~= '' then
if not options.plain then
formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id )
end
table.insert( formattedClaims, formattedStatement )
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
---Create context
---@param initOptions table
---@return table | nil
local function initContext( initOptions )
local context = {
entityId = initOptions.entityId,
entity = initOptions.entity,
extractCategory = extractCategory,
formatSnak = formatSnak,
formatPropertyDefault = formatPropertyDefault,
formatStatementDefault = formatStatementDefault,
getPropertyInBoundaries = getPropertyInBoundaries,
getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty,
getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties,
getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier,
getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers,
parseTimeFromSnak = p._parseTimeFromSnak,
getLabelWithLang = getLabelWithLang,
wrapSnak = wrapSnak,
wrapStatement = wrapStatement,
wrapQualifier = wrapQualifier,
}
context.cloneOptions = function( options )
local entity = options.entity
options.entity = nil
local newOptions = mw.clone( options )
options.entity = entity
newOptions.entity = entity
newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate()
return newOptions
end
context.formatProperty = function( options )
local func = getUserFunction( options, 'property', context.formatPropertyDefault )
return func( context, options )
end
context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end
context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end
context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end
context.parseTimeBoundariesFromSnak = function( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then
return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision )
end
return nil
end
context.getSourcingCircumstances = function( statement )
return getSourcingCircumstances( statement )
end
context.selectClaims = function( options, propertyId )
return selectClaims( context, options, propertyId )
end
return context
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param options table
---@return string Formatted wikitext.
local function formatProperty( options )
-- Получение сущности по идентификатору
local entity = getEntityFromId( options.entityId )
if not entity then
return -- throwError( 'entity-not-found' )
end
-- проверка на присутсвие у сущности заявлений (claim)
-- подробнее о заявлениях см. d:Викиданные:Глоссарий
if not entity.claims then
return '' --TODO error?
end
-- improve options
options.frame = g_frame
options.entity = entity
options.extends = function( self, newOptions )
return copyTo( newOptions, copyTo( self, {} ) )
end
if options.i18n then
options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) )
else
options.i18n = getConfig( 'i18n' )
end
local context = initContext( options )
return context.formatProperty( options )
end
---Функция для оформления одного утверждения (statement)
---@param context table
---@param options table
---@param statement table
---@return string Formatted wikitext.
function formatStatement( context, options, statement )
if not statement then
error( 'statement is not specified or nil' )
end
if not statement.type or statement.type ~= 'statement' then
throwError( 'unknown-claim-type' )
end
local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault )
return functionToCall( context, options, statement )
end
---@param statement table
---@return table
function getSourcingCircumstances( statement )
if not statement then
error( 'statement is not specified' )
end
local circumstances = {}
if statement.qualifiers and statement.qualifiers.P1480 then
for _, qualifier in pairs( statement.qualifiers.P1480 ) do
if qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid'
and qualifier.datavalue.value
and qualifier.datavalue.value[ 'entity-type'] == 'item'
then
table.insert( circumstances, qualifier.datavalue.value.id )
end
end
end
return circumstances
end
---Функция для оформления одного утверждения (statement)
---@param context table Context.
---@param options table Parameters.
---@param statement table
---@return string Formatted wikitext.
function formatStatementDefault( context, options, statement )
if not context then error( 'context is not specified' ) end
if not options then error( 'options is not specified' ) end
if not statement then error( 'statement is not specified' ) end
local circumstances = context.getSourcingCircumstances( statement )
options.qualifiers = statement.qualifiers
local result = context.formatSnak( options, statement.mainsnak, circumstances )
if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then
local qualifierConfig = getPropertyParams( options.qualifier, nil, {} )
if options.i18n then
qualifierConfig.i18n = options.i18n
end
if qualifierConfig.datatype == 'time' then
qualifierConfig.nolinks = true
end
local qualifierValues = {}
for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do
local snakValue = context.formatSnak( qualifierConfig, qualifierSnak )
if snakValue and snakValue ~= '' then
table.insert( qualifierValues, snakValue )
end
end
if result and result ~= '' and #qualifierValues then
if qualifierConfig.invisible then
result = result .. table.concat( qualifierValues, ', ' )
else
result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')'
end
end
end
if result and result ~= '' and options.references then
result = result .. context.formatRefs( options, statement )
end
return result
end
---Функция для оформления части утверждения (snak)
---Подробнее о snak см. d:Викиданные:Глоссарий
---@param context table Context.
---@param options table Parameters.
---@param snak table
---@param circumstances table
---@return string Formatted wikitext.
function formatSnak( context, options, snak, circumstances )
circumstances = circumstances or {}
local result
if snak.snaktype == 'somevalue' then
if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then
result = options[ 'somevalue' ]
else
result = options.i18n[ 'somevalue' ]
end
elseif snak.snaktype == 'novalue' then
if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then
result = options[ 'novalue' ]
else
result = options.i18n[ 'novalue' ]
end
elseif snak.snaktype == 'value' then
result = formatDatavalue( context, options, snak.datavalue, snak.datatype )
for _, item in pairs( circumstances ) do
if options.i18n[ item ] then
result = options.i18n[ item ] .. result
end
end
else
throwError( 'unknown-snak-type' )
end
if not result or result == '' then
return nil
end
if options.plain then
return result
end
return context.wrapSnak( result, snak.hash )
end
---Функция для оформления объектов-значений с географическими координатами
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatGlobeCoordinate( value, options )
-- проверка на требование в параметрах вызова на возврат сырого значения
if options[ 'subvalue' ] == 'latitude' then -- широты
return value[ 'latitude' ]
elseif options[ 'subvalue' ] == 'longitude' then -- долготы
return value[ 'longitude' ]
elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then
-- если передан параметр nocoord, то не выводить координаты
-- обычно это делается при использовании нескольких карточек на странице
return ''
else
-- в противном случае формируются параметры для вызова шаблона {{coord}}
-- нужно дописать в документации шаблона, что он отсюда вызывается, и что
-- любое изменние его парамеров должно быть согласовано с кодом тут
local coordModule = require( 'Module:Coordinates' )
local globe = options.globe or ''
if globe == '' and value[ 'globe' ] then
local globes = require( 'Module:Wikidata/Globes' )
globe = globes[ value[ 'globe' ] ] or ''
end
local display = 'inline'
if options.display and options.display ~= '' then
display = options.display
elseif ( options.property:upper() == 'P625' ) then
display = 'title'
end
local format = options.format or ''
if format == '' then
format = 'dms'
if value[ 'precision' ] then
local precision = value[ 'precision' ] * 60
if precision >= 60 then
format = 'd'
elseif precision >= 1 then
format = 'dm'
end
end
end
g_frame.args = {
tostring( value[ 'latitude' ] ),
tostring( value[ 'longitude' ] ),
globe = globe,
type = options.type and options.type or '',
scale = options.scale and options.scale or '',
display = display,
format = format,
}
return coordModule.coord(g_frame)
end
end
---Функция для оформления объектов-значений с файлами с Викисклада
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatCommonsMedia( value, options )
local image = value
local caption = ''
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
caption = options[ 'caption' ]
end
if caption ~= '' then
caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } )
end
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]]
image = '[[File:' .. value .. '|frameless'
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border'
end
local size = options[ 'size' ]
if size and size ~= '' then
-- TODO: check localized pixel names too
if not string.match( size, 'px$' ) then
size = size .. 'px'
end
else
size = fileDefaultSize
end
image = image .. '|' .. size
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ]
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]'
if caption ~= '' then
image = image .. '<br>' .. caption
end
else
image = image .. caption .. getCategoryByCode( 'media-contains-markup' )
end
return image
end
---Function for render math formulas
---@param value string Value.
---@param options table Parameters.
---@return string Formatted string.
local function formatMath( value, options )
return options.frame:extensionTag{ name = 'math', content = value }
end
---Функция для оформления внешних идентификаторов
---@param value string
---@param options table
---@return string
local function formatExternalId( value, options )
local formatter = options.formatter
local propertyId = options.property:upper()
if not formatter or formatter == '' then
local isGoodFormat = false
local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' )
if wbStatus and formatRegexStatements then
for _, statement in pairs( formatRegexStatements ) do
if statement.mainsnak.snaktype == 'value' then
local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' )
pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' )
if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' )
or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then
isGoodFormat = true
break
end
end
end
end
if isGoodFormat then
local formatterStatements
wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' )
if wbStatus and formatterStatements then
for _, statement in pairs( formatterStatements ) do
if statement.mainsnak.snaktype == 'value' then
formatter = statement.mainsnak.datavalue.value
break
end
end
end
end
end
if formatter and formatter ~= '' then
local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub
local link = mw.ustring.gsub(
mw.ustring.gsub( formatter, '$1', encodedValue ), '.',
{ [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } )
local title = options.title
if not title or title == '' then
title = '$1'
end
title = mw.ustring.gsub(
mw.ustring.gsub( title, '$1', encodedValue ), '.',
{ [ '[' ] = '(', [ ']' ] = ')' } )
return '[' .. link .. ' ' .. title .. ']'
end
return value
end
---Функция для оформления числовых значений
---@param value table Объект-значение
---@param options table Таблица параметров
---@return string Оформленный текст
local function formatQuantity( value, options )
-- диапазон значений
local amount = string.gsub( value.amount, '^%+', '' )
local lang = mw.language.getContentLanguage()
local langCode = lang:getCode()
local function formatNum( number, sigfig )
local multiplier = ''
if options.countByThousands then
local powers = options.i18n.thousandPowers
local pos = 1
while math.abs( number ) >= 1000 and pos < #powers do
number = number / 1000
pos = pos + 1
end
multiplier = powers[ pos ]
if math.abs( number ) >= 100 then
sigfig = sigfig or 0
elseif math.abs( number ) >= 10 then
sigfig = sigfig or 1
else
sigfig = sigfig or 2
end
else
sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности
end
local iMultiplier = 10^sigfig
number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier
return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier
end
local out = formatNum( tonumber( amount ) )
if value.upperBound then
local diff = tonumber( value.upperBound ) - tonumber( amount )
if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local bound = formatNum( diff, precision )
if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате
local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2
bound = formatNum( diff * 10 ^ digits, precision )
bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 )
end
out = out .. ' ± ' .. bound
end
end
if options.unit and options.unit ~= '' then
if options.unit ~= '-' then
out = out .. ' ' .. options.unit
end
elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then
local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' )
if unitEntityId ~= 'undefined' then
local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
if wbStatus == true and unitEntity then
if unitEntity.claims.P2370 and
unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and
not value.upperBound and
options.siConversion == true
then
local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' )
if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then
-- Если не степени десятки (переводить сантиметры в метры не надо!)
local outValue = tonumber( amount ) * conversionToSiUnit
if outValue > 0 then
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 )
local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 )
out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) )
else
out = formatNum( outValue, 0 )
end
unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' )
wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
end
end
local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, {
'P5061[language:' .. langCode .. ']',
'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']',
'P558[!P282][!P407]'
} )
out = out .. ' ' .. label
end
end
end
return out
end
---Функция для оформления URL
---@param context table
---@param options table
---@param value string
local function formatUrlValue( context, options, value )
if not options.length or options.length == '' then
options.length = 25
end
local moduleUrl = require( 'Module:URL' )
return moduleUrl.formatUrlSingle( context, options, value )
end
local DATATYPE_CACHE = {}
---Get property datatype by ID.
---@param propertyId string Property ID, e.g. 'P123'.
---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'.
local function getPropertyDatatype( propertyId )
if not propertyId or not string.match( propertyId, '^P%d+$' ) then
return nil
end
local cached = DATATYPE_CACHE[ propertyId ]
if cached ~= nil then
return cached
end
local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId )
if wbStatus ~= true or not propertyEntity then
return nil
end
mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' )
DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype
return propertyEntity.datatype
end
---@param datavalue table
---@return function
local function getPlainValueFunction( datavalue, _ )
if datavalue.type == 'wikibase-entityid' then
return function( _, _, value )
return getEntityIdFromValue( value )
end
elseif datavalue.type == 'string' then
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
return function( _, _, value )
return value.text
end
elseif datavalue.type == 'globecoordinate' then
return function( _, _, value )
return value.latitude .. ',' .. value.longitude
end
elseif datavalue.type == 'quantity' then
return function( _, _, value )
return value.amount
end
elseif datavalue.type == 'time' then
return function( _, _, value )
return value.time
end
end
throwError( 'unknown-datavalue-type' )
end
---@param datavalue table
---@param datatype string
---@return function
local function getDefaultValueFunction( datavalue, datatype )
-- вызов обработчиков по умолчанию для известных типов значений
if datavalue.type == 'wikibase-entityid' then
-- Entity ID
return function( context, options, value )
return formatEntityId( context, options, getEntityIdFromValue( value ) )
end
elseif datavalue.type == 'string' then
-- String
if datatype and datatype == 'commonsMedia' then
-- Media
return function( _, options, value )
return formatCommonsMedia( value, options )
end
elseif datatype and datatype == 'external-id' then
-- External ID
return function( _, options, value )
return formatExternalId( value, options )
end
elseif datatype and datatype == 'math' then
-- Math formula
return function( _, options, value )
return formatMath( value, options )
end
elseif datatype and datatype == 'url' then
-- URL
return formatUrlValue
end
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
-- моноязычный текст (строка с указанием языка)
return function( _, options, value )
if options.monolingualLangTemplate == 'lang' then
if value.language == CONTENT_LANGUAGE_CODE then
return value.text
end
return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } }
elseif options.monolingualLangTemplate == 'ref' then
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language }
else
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>'
end
end
elseif datavalue.type == 'globecoordinate' then
-- географические координаты
return function( _, options, value )
return formatGlobeCoordinate( value, options )
end
elseif datavalue.type == 'quantity' then
return function( _, options, value )
return formatQuantity( value, options )
end
elseif datavalue.type == 'time' then
return function( context, options, value )
local moduleDate = require( 'Module:Wikidata/date' )
return moduleDate.formatDate( context, options, value )
end
end
-- во всех стальных случаях возвращаем ошибку
throwError( 'unknown-datavalue-type' )
end
---Функция для оформления значений (value)
---Подробнее о значениях см. d:Wikidata:Glossary/ru
---@param context table
---@param options table
---@param datavalue table
---@param datatype string
---@return string Оформленный текст
function formatDatavalue( context, options, datavalue, datatype )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not datavalue then error( 'datavalue not specified' ); end
if not datavalue.value then error( 'datavalue.value is missing' ); end
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options.plain then
context.formatValueDefault = getPlainValueFunction( datavalue, datatype )
else
context.formatValueDefault = getDefaultValueFunction( datavalue, datatype )
end
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault )
return functionToCall( context, options, datavalue.value )
end
local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000}
---Функция для оформления идентификатора сущности
---@param context table
---@param options table
---@param entityId string
---@return string Оформленный текст
function formatEntityId( context, options, entityId )
-- получение локализованного названия
local boundaries
if options.qualifiers then
boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } )
end
if not boundaries then
boundaries = DEFAULT_BOUNDARIES
end
local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries )
-- определение соответствующей показываемому элементу категории
local category = context.extractCategory( options, { id = entityId } )
-- получение ссылки по идентификатору
local link = mw.wikibase.sitelink( entityId )
if link then
-- ссылка на категорию, а не добавление страницы в неё
if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then
link = ':' .. link
end
if label and not options.rawArticle then
if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then
label = '<span lang="' .. label .. '">' .. label .. '</span>'
end
local a = '[[' .. link .. '|' .. label .. ']]'
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return a .. category
else
return '[[' .. link .. ']]' .. category
end
end
if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId)
-- красная ссылка
-- TODO: разобраться, почему не всегда есть options.frame
local moduleRedLink = require( 'Module:Wikidata/redLink' )
local title = mw.title.new( label )
if title and not title.exists and options.frame then
local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль
local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId)
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' ..
getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return redLink .. category
end
-- TODO: перенести до проверки на существование статьи
local addWdLink = false
if ( not options.format or options.format ~= 'text' )
and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text
then
addWdLink = true
end
-- одноимённая статья уже существует - выводится текст и ссылка на ВД
return moduleRedLink.formatText(label, entityId, addWdLink) .. category
end
-- сообщение об отсутвии локализованного названия
-- not good, but better than nothing
return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@deprecated Use p.formatProperty() instead
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatStatements( frame )
return p.formatProperty( frame )
end
---Получение параметров, которые обычно используются для вывода свойства.
---@param propertyId string
---@param datatype string
---@param params table
function getPropertyParams( propertyId, datatype, params )
local config = getConfig()
-- Различные уровни настройки параметров, по убыванию приоритета
local propertyParams = {}
-- 1. Параметры, указанные явно при вызове
if params then
for key, value in pairs( params ) do
if value ~= '' then
propertyParams[ key ] = value
end
end
end
if toBoolean( propertyParams.plain, false ) then
propertyParams.separator = propertyParams.separator or ', '
propertyParams.conjunction = propertyParams.conjunction or ', '
else
-- 2. Настройки конкретного параметра
if config.properties and config.properties[ propertyId ] then
for key, value in pairs( config.properties[ propertyId ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 3. Указанный пресет настроек
if propertyParams.preset and config.presets and
config.presets[ propertyParams.preset ]
then
for key, value in pairs( config.presets[ propertyParams.preset ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId )
if propertyParams.datatype == nil then
propertyParams.datatype = datatype
end
-- 4. Настройки для типа данных
if datatype and config.datatypes and config.datatypes[ datatype ] then
for key, value in pairs( config.datatypes[ datatype ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 5. Общие настройки для всех свойств
if config.global then
for key, value in pairs( config.global ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
end
return propertyParams
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatProperty( frame )
local args = copyTo( frame.args, {} )
-- проверка на отсутствие обязательного параметра property
if not args.property then
throwError( 'property-param-not-provided' )
end
local override
local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w)
if string.sub( w, 1, 1 ) == '~' then
override = w
end
return ''
end ) )
if override then
args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' )
args.property = propertyId
end
-- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно
local p_frame = frame
while p_frame do
if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then
copyTo( p_frame.args, args, true )
end
if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then
args.entityId = p_frame.args.from
else
args.entityId = mw.wikibase.getEntityIdForCurrentPage()
end
p_frame = p_frame:getParent()
end
args = getPropertyParams( propertyId, nil, args )
local datatype = args.datatype
-- перевод итоговых значений флагов в true/false и добавление значений
-- по умолчанию только в том случае, если они нигде не были указаны ранее
args.plain = toBoolean( args.plain, false )
args.nocat = not args.plain and toBoolean( args.nocat, false )
args.references = not args.plain and toBoolean( args.references, true )
-- если значение передано в параметрах вызова то выводим только его
if args.value and args.value ~= '' then
-- специальное значение для скрытия Викиданных
if args.value == '-' then
return ''
end
local value = args.value
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if args.plain then
return value
end
local context = initContext( args )
-- обработчики по типу значения
local wrapperExtraArgs = {}
if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then
local func = getUserFunction( args, 'value' )
value = func( context, args, value )
elseif datatype == 'commonsMedia' then
value = formatCommonsMedia( value, args )
elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then
wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value )
value = formatExternalId( value, args )
--elseif datatype == 'math' then
-- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag
-- value = formatMath( value, args )
elseif datatype == 'url' then
value = formatUrlValue( context, args, value )
end
-- оборачиваем в тег для JS-функций
if string.match( propertyId, '^P%d+$' ) then
value = mw.text.trim( value )
-- временная штрафная категория для исправления табличных вставок
local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables
if not allowTables
and string.match( value, '<t[dhr][ >]' )
-- and not string.match( value, '<table[ >]' )
-- and not string.match( value, '^%{%|' )
then
value = value .. getCategoryByCode( 'value-contains-table', propertyId )
else
value = wrapStatement( value, propertyId, nil, wrapperExtraArgs )
end
end
return value
end
-- ability to disable loading Wikidata
if args.entityId == '-' then
return ''
end
g_frame = frame
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений)
return formatProperty( args )
end
---Функция проверки на присутствие источника в списке нерекомендованных.
---@param snaks table
---@return boolean
local function isReferenceDeprecated( snaks )
if not snaks then
return false
end
if snaks.P248
and snaks.P248[ 1 ]
and snaks.P248[ 1 ].datavalue
and snaks.P248[ 1 ].datavalue.value.id
then
local entityId = snaks.P248[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
elseif snaks.P1433
and snaks.P1433[ 1 ]
and snaks.P1433[ 1 ].datavalue
and snaks.P1433[ 1 ].datavalue.value.id
then
local entityId = snaks.P1433[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
end
return false
end
---Функция оформления ссылок на источники (reference)
---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru
---
---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context
---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства).
---@param context table
---@param options table
---@param statement table
---@return string Оформленные примечания для отображения в статье
function formatRefs( context, options, statement )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
if not statement then error( 'statement not specified' ); end
if not outputReferences then
return ''
end
---@type string[]
local references = {}
if statement.references then
local hasNotDeprecated = false
local displayCount = 0
for _, reference in pairs( statement.references ) do
if not isReferenceDeprecated( reference.snaks ) then
hasNotDeprecated = true
end
end
for _, reference in pairs( statement.references ) do
local display = true
if hasNotDeprecated then
if isReferenceDeprecated( reference.snaks ) then
display = false
end
end
if displayCount >= 2 then
if options.entityId and options.property then
local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше
local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>'
table.insert( references, moreReferences )
end
break
end
if display == true then
---@type string
local refText = moduleSources.renderReference( g_frame, options.entityId, reference )
if refText and refText ~= '' then
table.insert( references, refText )
displayCount = displayCount + 1
end
end
end
end
return table.concat( references )
end
return p
4558f762f30c6ebfb9f5333dbd7ebda83c6873f2
Модуль:Wikidata/media
828
88
186
2024-10-26T15:20:21Z
wikipedia, ruwikipedia>Stjn
0
[[ВП:×|отмена]]: сломало отображение в множестве статей
Scribunto
text/plain
local p = {}
-- Константы
local contentLanguageCode = mw.getContentLanguage():getCode();
function p.formatCommonsCategory( context, options, value )
local link = 'commons:Category:' .. value
local title = value .. ' на Викискладе'
if ( options['text'] and options['text'] ~= '' ) then
title = options['text']
end
commons = '[[' .. link .. '|' .. title .. ']]'
--Commons icon
if ( not options['icon'] or options['icon'] ~= '-' ) then
local icon_size = '15px'
if ( options['icon_size'] and options['icon_size'] ~= '' ) then
icon_size = options['icon_size']
end
commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons
end
--Text before and after link
if ( options['text_before'] and options['text_before'] ~= '' ) then
if ( options['text_before'] ~= '-' ) then
commons = options['text_before'] .. ' ' .. commons
end
end
if ( options['text_after'] and options['text_after'] ~= '' ) then
if ( options['text_after'] ~= '-' ) then
commons = commons .. ' ' .. options['text_after']
end
end
return commons
end
--[[
Временный хак, нужно добавить config, getConfig и getCategoryByCode
в options, чтобы они были доступны в любом месте кода.
]]
local config;
local function getCategoryByCode( code, sortkey )
if config == nil then
config = require( 'Module:Wikidata/config' );
end;
local value = config[ 'categories' ][ code ];
if not value or value == '' then
return '';
end
return '[[Category:' .. value .. ']]';
end
local function getCaption( context, options )
local caption = ''
if options.qualifiers and options.qualifiers.P2096 then
for i, qualifier in pairs( options.qualifiers.P2096 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'monolingualtext'
and qualifier.datavalue.value
and qualifier.datavalue.value.language == contentLanguageCode ) then
caption = qualifier.datavalue.value.text
break
end
end
end
if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then
local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue )
if not caption or caption == '' then
caption = moment
else
caption = caption .. ', ' .. moment
end
end
local localValue = '';
if options[ 'value' ] and options[ 'value' ] ~= '' then
localValue = options[ 'value' ];
end
local localCaption = '';
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
localCaption = options[ 'caption' ];
end
if localValue ~= '' then
caption = localCaption;
end
local formattedCaption = ''
if caption ~= '' then
formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } );
end
if localValue == '' and localCaption ~= '' then
formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' )
if options.frame:preprocess('{{REVISIONID}}') == '' then
formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>'
end
end
return caption, formattedCaption
end
function p.formatCommonsMediaValue( context, options, value )
local image = value;
local caption, formattedCaption = getCaption( context, options )
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]]
image = '[[File:' .. value .. '|frameless';
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border';
end
local size = options[ 'size' ];
if size and size ~= '' then
if not string.match( size, 'px$' )
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
then
size = size .. 'px'
end
-- временно
if string.match( size, 'pxpx' ) then
image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image
end
else
size = fileDefaultSize;
end
image = image .. '|' .. size;
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ];
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]';
if formattedCaption ~= '' then
image = image .. '<br>' .. formattedCaption;
end
else
image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' );
end
if options.entity and options.fixdouble then
local page = mw.title.getCurrentTitle()
local txt = page:getContent()
if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then
if options.frame:preprocess('{{REVISIONID}}') == '' then
image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>'
end
image = image .. getCategoryByCode( 'media-contains-local-double' )
end
end
return image
end
return p
ec384e72491465f4103cce95a8f9467df428a432
Модуль:String
828
27
64
2024-11-18T02:41:06Z
wikipedia, ruwikipedia>Stjn
0
аналогично английскому разделу — mw.ustring.gsub тут не нужен
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
subcount
This function returns the count of substring in source string.
Usage:
{{#invoke:String|subcount|source_string|substring|plain_flag}}
OR
{{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
plain: A flag indicating that the substring should be understood as plain
text. Defaults to true.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.subcount( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} );
local s = new_args['s'] or '';
local plain_flag = str._getBoolean( new_args['plain'] or true );
local pattern = new_args['pattern'] or '';
if s == '' or pattern == '' then
return 0;
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local _, count = mw.ustring.gsub(s, pattern, "")
return count;
end
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local s = new_args['s'] or '';
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local s = new_args['s'] or '';
local i = tonumber( new_args['i'] ) or 1;
local j = tonumber( new_args['j'] ) or -1;
local len = mw.ustring.len( s );
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1;
end
if j < 0 then
j = len + j + 1;
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'Значение индекса подстроки выходит за допустимые границы' );
end
if j < i then
return str._error( 'Неверный порядок индексов подстроки' );
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local s = new_args['s'] or '';
local start = tonumber( new_args['start'] ) or 1;
local plain_flag = str._getBoolean( new_args['plain'] or false );
local pattern = new_args['pattern'] or '';
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local nomatch = new_args['nomatch'];
if s == '' then
return str._error( 'Пустая строка поиска' );
end
if pattern == '' then
return str._error( 'Пустой шаблон поиска' );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Индекс начала поиска выходит за допустимые границы' );
end
if match_index == 0 then
return str._error( 'Индекс совпадения выходит за допустимые границы' );
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start );
end
local iterator = mw.ustring.gmatch(s, pattern);
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1;
if match_index == 0 then
result = w;
break;
end
end
else
-- Reverse search
local result_table = {};
local count = 1;
for w in iterator do
result_table[count] = w;
count = count + 1;
end
result = result_table[ count + match_index ];
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Совпадение не найдено' );
else
return nomatch;
end
else
return result;
end
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local target_str = new_args['target'] or '';
local pos = tonumber( new_args['pos'] ) or 0;
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'Значение индекса строки выходит за допустимые границы' );
end
return mw.ustring.sub( target_str, pos, pos );
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} );
local source_str = new_args['source'] or '';
local target_str = new_args['target'] or '';
if target_str == '' then
return 1;
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['target'] or '';
local start_pos = tonumber(new_args['start']) or 1;
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return 0;
end
plain = str._getBoolean( plain );
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['pattern'] or '';
local replace = new_args['replace'] or '';
local count = tonumber( new_args['count'] );
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return source_str;
end
plain = str._getBoolean( plain );
if plain then
pattern = str._escapePattern( pattern );
replace = string.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences.
end
local result;
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count );
else
result = mw.ustring.gsub( source_str, pattern, replace );
end
return result;
end
--[[
This function adds support for escaping parts of the patterns when using [plain=false].
]]
function str.escape( frame )
local new_args = str._getParameters( frame.args, {'pattern' } );
local pattern = new_args['pattern'] or '';
local result = '';
result = str._escapePattern( pattern );
return result;
end
--[[
Internal compare string function
]]
function str._strcmp(a , b)
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
local c2 = s2c();
if c1 == nil then
if c2 == nil then
return 0
else
return -1
end
else
if c2 ~= nil then
if c1 ~= c2 then
return c1 < c2 and -1 or 1
end
else
return 1
end
end
end
return 0
end
--[[
compare
This function compare two UTF-8 strings
Usage:
{{#invoke:String|compare|str1|str2}}
Returns:
0 - if strings are equal
1 - if st1 > str2
-1 - if str1 < str2
]]
function str.compare(frame)
local str1 = frame.args[1] or '';
local str2 = frame.args[2] or '';
return str._strcmp(str1 , str2)
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Страницы с ошибками модуля String';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if str._getBoolean(ignore_errors) then
return '';
end
local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>';
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Категория:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'Логическое значение не найдено' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return ( string.gsub( pattern_str, "[%(%)%.%%%+%-%*%?%[%^%$%]]", "%%%0" ) )
end
return str
2c7347f1dafbbc0efc196c148a1f81e7b82420dc
Модуль:Wikidata/config
828
85
180
2024-12-15T07:54:37Z
wikipedia, ruwikipedia>Putnik
0
на всякий случай, чтобы избежать ненужных сносок
Scribunto
text/plain
-- Property configuration for Wikidata module
return {
global = {
separator = ', ',
conjunction = ' и ',
},
presets = {
['catonly'] = {
datatype = 'wikibase-item',
conjunction = '',
invisible = true,
['value-module'] = 'Wikidata/item',
['value-function'] = 'formatCategoryOnly',
references = '',
category = 'P910',
},
['country'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatCountryClaimWithFlag',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['from-to'] = {
datatype = 'time',
['property-module'] = 'Wikidata/date',
['property-function'] = 'formatDateIntervalProperty',
},
['link'] = {
['value-module'] = 'Wikidata/link',
['value-function'] = 'fromModule',
},
['list'] = {
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['name'] = {
datatype = 'monolingualtext',
monolingualLangTemplate = 'lang',
separator = '<br>',
conjunction = '<br>',
},
['place'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatPlaceWithQualifiers',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['quantity (date)'] = {
datatype = 'quantity',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
qualifier = 'P585',
},
},
datatypes = {
commonsMedia = {
limit = 1,
references = false,
size = '274x400px',
separator = '<br>',
conjunction = '<br>',
somevalue = '',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsMediaValue',
},
['external-id'] = {
references = false,
},
['globe-coordinate'] = {
limit = 1,
references = false,
},
url = {
separator = '<br>',
conjunction = '<br>',
references = false,
['value-module'] = 'Wikidata/url',
['value-function'] = 'formatUrlValue',
},
quantity = {
siConversion = true
}
},
properties = {
P6 = { datatype = 'wikibase-item', },
P17 = {
preset = 'country',
},
P18 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P19 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P20 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P22 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P25 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P26 = { datatype = 'wikibase-item', },
P27 = {
preset = 'country',
},
P31 = {
datatype = 'wikibase-item',
references = false,
},
P37 = { datatype = 'wikibase-item', },
P39 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/positions',
['claim-function'] = 'formatPositionClaim',
separator = '',
conjunction = '',
allowTables = true,
},
P40 = { datatype = 'wikibase-item', },
P41 = {
datatype = 'commonsMedia',
size = '150x200px',
},
P53 = {
datatype = 'wikibase-item',
category = 'P910',
},
P54 = {
category = 'P6112',
},
P57 = {
datatype = 'wikibase-item',
preset = 'list',
},
P58 = {
datatype = 'wikibase-item',
preset = 'list',
},
P59 = {
datatype = 'wikibase-item',
category = 'P910',
references = false,
},
P69 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P3876',
qualifier = 'P582',
},
P94 = {
datatype = 'commonsMedia',
size = '100x200px',
},
P86 = {
datatype = 'wikibase-item',
preset = 'list',
},
P101 = { datatype = 'wikibase-item', },
P102 = {
datatype = 'wikibase-item',
preset = 'list',
qualifier = 'P582',
category = 'P6365',
},
P103 = { datatype = 'wikibase-item', },
P106 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
},
P108 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P4195',
},
P109 = {
datatype = 'commonsMedia',
size = '150x150px',
alt = 'Изображение автографа',
},
P117 = {
datatype = 'commonsMedia',
size = '290x300px',
alt = 'Изображение химической структуры',
},
P119 = {
preset = 'place',
thisLocationOnly = 'true',
},
P131 = { datatype = 'wikibase-item', },
P140 = {
datatype = 'wikibase-item',
},
P154 = {
size = '220x80px',
alt = 'Изображение логотипа',
},
P159 = {
preset = 'place',
},
P161 = {
preset = 'list',
},
P162 = {
preset = 'list',
},
P163 = { datatype = 'wikibase-item', },
P166 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/Medals',
['property-function'] = 'formatProperty',
['value-module'] = 'Wikidata/Medals',
['value-function'] = 'formatValue',
before = '<div style="text-align:justify">',
after = '</div>',
separator = ' ',
conjunction = ' ',
references = false,
allowTables = true,
},
P190 = { datatype = 'wikibase-item', },
P212 = {
preset = 'link',
},
P225 = {
preset = 'list',
['claim-module'] = 'Wikidata/Biology',
['claim-function'] = 'formatTaxonNameClaim',
},
P237 = { datatype = 'wikibase-item', },
P241 = { datatype = 'wikibase-item', },
P242 = {
datatype = 'commonsMedia',
size = '300x300px',
},
P247 = {
formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1',
},
P267 = {
preset = 'link',
},
P276 = {
preset = 'place',
},
P281 = { datatype = 'string', },
P286 = {
preset = 'list',
},
P296 = {
formatter = 'http://osm.sbin.ru/esr/esr:$1',
},
P301 = {
rawArticle = true,
},
P344 = {
preset = 'list',
},
P345 = {
preset = 'link',
},
P348 = {
preset = 'list',
['property-module'] = 'Wikidata/Software',
['property-function'] = 'formatVersionProperty',
},
P361 = { datatype = 'wikibase-item', },
P373 = {
datatype = 'string',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsCategory',
limit = 1,
references = false,
},
P374 = { datatype = 'external-id', },
P395 = { datatype = 'string', },
P407 = { datatype = 'wikibase-item', },
P410 = { datatype = 'wikibase-item', },
P412 = {
datatype = 'wikibase-item',
category = 'P910',
},
P413 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
category = 'P910',
},
P414 = {
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'applyDefaultTemplate',
},
P421 = { datatype = 'wikibase-item', },
P473 = { datatype = 'string', },
P495 = {
preset = 'country',
},
P505 = {
preset = 'list',
},
P512 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/P512',
['property-function'] = 'formatAcademicDegree',
},
P527 = {
preset = 'list',
},
P528 = {
references = false,
qualifier = 'P972',
},
P551 = {
preset = 'place',
},
P569 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfBirthClaim',
},
P570 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfDeathClaim',
},
P571 = { datatype = 'time', },
P576 = { datatype = 'time', },
P598 = { datatype = 'wikibase-item', },
P607 = {
datatype = 'wikibase-item',
preset = 'list',
},
P625 = { datatype = 'globe-coordinate', },
P669 = {
qualifier = 'P670',
},
P685 = {
formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1',
},
P721 = {
preset = 'link',
},
P764 = {
preset = 'link',
},
P803 = { datatype = 'wikibase-item', },
P856 = { datatype = 'url', },
P881 = {
novalue = 'нет',
category = 'P910',
},
P884 = {
preset = 'link',
},
P915 = {
category = 'P1740',
},
P957 = {
preset = 'link',
},
P972 = {
preset = 'catonly',
},
P1077 = {
preset = 'link',
},
P1082 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1098 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1120 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1128 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1114 = {
datatype = 'quantity',
qualifier = 'P585',
},
P1174 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1195 = {
['value-module'] = 'Wikidata/Software',
['value-function'] = 'formatExtension',
conjunction = ' или ',
},
P1215 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatVisualMagnitude'
},
P1246 = {
preset = 'link',
},
P1249 = { datatype = 'time', },
P1352 = { preset = 'quantity (date)', },
P1376 = { datatype = 'wikibase-item', },
P1402 = {
preset = 'link',
},
P1448 = {
preset = 'name',
},
P1458 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatColorIndex'
},
P1464 = { datatype = 'wikibase-item', },
P1476 = {
preset = 'name',
},
P1477 = {
preset = 'name',
},
P1532 = {
preset = 'country',
rank = '[rank:normal, rank:preferred]',
},
P1543 = {
datatype = 'commonsMedia',
},
P1559 = {
preset = 'name',
},
P1603 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1621 = {
size = '300x300px',
},
P1692 = {
preset = 'link',
},
P1705 = {
preset = 'name',
},
P1753 = {
rowArticle = true,
},
P1809 = {
preset = 'list',
},
P1846 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P2031 = {
preset = 'from-to',
to = 'P2032',
within = 'P570',
},
P2043 = {
preset = 'quantity (date)',
},
P2044 = { datatype = 'quantity', },
P2046 = {
preset = 'quantity (date)',
siConversion = false,
},
P2047 = {
siConversion = false,
},
P2048 = {
conjunction = ' или ',
},
P2060 = {
siConversion = false,
},
P2097 = {
siConversion = false,
},
P2120 = {
siConversion = false,
},
P2137 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2139 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2146 = {
siConversion = false,
},
P2214 = {
siConversion = false
},
P2226 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2257 = {
siConversion = false
},
P2260 = {
siConversion = false
},
P2295 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2324 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.'
},
P2403 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2425 = {
alt = 'Изображение орденской планки',
},
P2583 = {
siConversion = false,
},
P2597 = {
preset = 'catonly',
},
P2650 = { datatype = 'wikibase-item', },
P2789 = {
preset = 'list',
},
P2896 = {
siConversion = false,
},
P2910 = {
size = '100x80px',
},
P3083 = {
formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1',
},
P3086 = {
siConversion = false,
},
P3362 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P4614 = {
category = 'P1200',
},
P5348 = {
siConversion = false,
},
P6257 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatRA',
},
P6258 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatDMS',
},
P6259 = {
['references'] = false,
},
P7584 = {
siConversion = false,
},
P8010 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P8224 = {
alt = 'Изображение молекулярной модели',
},
},
categories = {
['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи',
['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные',
['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи',
['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных',
['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки',
['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке',
['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке',
},
errors = {
['property-param-not-provided'] = 'Не дан параметр свойства',
['entity-not-found'] = 'Сущность не найдена.',
['unknown-claim-type'] = 'Неизвестный тип заявления.',
['unknown-snak-type'] = 'Неизвестный тип снэка.',
['unknown-datavalue-type'] = 'Неизвестный тип значения данных.',
['unknown-entity-type'] = 'Неизвестный тип сущности.',
['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.',
['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.',
['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.',
['property-module-not-found'] = 'Модуль для отображения свойства не найден',
['property-function-not-found'] = 'Функция для отображения свойства не найдена',
['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.',
['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.',
['value-module-not-found'] = 'Модуль для отображения значения не найден.',
['value-function-not-found'] = 'Функция для отображения значения не найдена.',
},
i18n = {
somevalue = "''неизвестно''",
novalue = '',
-- Обстоятельства источника
Q5727902 = 'около ',
Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ',
Q30230067 = 'возможно ',
Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем"><</span> ',
Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">></span> ',
Q60070514 = 'примерно ',
thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'},
},
deprecatedSources = {
Q355 = true, -- Facebook
Q36578 = true, -- Gemeinsame Normdatei
Q63056 = true, -- Find a Grave
Q212256 = true, -- АиФ
Q504063 = true, -- Discogs
Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748
Q1798125 = true, -- LIBRIS
Q2621214 = true, -- Geni
Q15222191 = true, -- BNF
Q15241312 = true, -- Freebase
Q19938912 = true, -- BNF
Q21697707 = true, -- Хайазг
Q25328680 = true, -- Prabook
Q29861311 = true, -- SNAC
Q86999151 = true, -- WeChangEd
},
};
bd6091486f675bebf109cb52de53a162b05a5243
Шаблон:Подстраницы шаблона Карточка
10
70
150
2025-01-02T20:14:31Z
wikipedia, ruwikipedia>Kaganer
0
* {{tnav|карточка/Викигид}}
wikitext
text/x-wiki
{{Навигационная таблица
|имя = Подстраницы шаблона Карточка
|state = {{{state|}}}
|класс_списков = hlist hlist-items-nowrap
|заголовок = Подстраницы шаблона {{tnav|Карточка}}
|tracking = <includeonly>no</includeonly>
|группа1 = {{!}}вверху=
|список1 =
* {{tnav|карточка/название}} (заголовок без уточнения)
* {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения)
|группа2 = {{!}}вверху2=
|список2 =
* {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]])
* {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]])
* {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]])
* {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]])
|группа3 = Разное
|список3 =
* {{tnav|карточка/изображение}}
* {{tnav|карточка/Изображение рядом}}
* {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]])
* {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]])
* {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]])
* {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]])
* {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]])
* {{tnav|карточка/блок}}
* {{tnav|карточка/блок с маркерами}}
|группа4 = {{!}}внизу=
|список4 =
* {{tnav|карточка/Викигид}}
* {{tnav|карточка/Викиданные}}
* {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]])
* {{tnav|карточка/Викитека}}
* {{tnav|карточка/Викиучебник}}
* {{tnav|карточка/Викицитатник}}
|класс_внизу = hlist
|внизу =
; См. также
: [[Википедия:Шаблоны-карточки]]
: [[:Категория:Шаблоны:Для шаблонов-карточек]]
}}<noinclude>
[[Категория:Навигационные шаблоны:Для шаблонов]]
</noinclude>
3fd4b54a761d9de6d7ddaac86889f4abf8478d95
Шаблон:Doc
10
53
116
2025-01-07T17:31:17Z
wikipedia, ruwikipedia>Stjn
0
не проверять страницы в основном пространстве на существование
wikitext
text/x-wiki
<includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}}
{{#if: {{{1|}}}
| {{#ifexist: {{#if: {{NAMESPACE:{{{1}}}}} | {{{1}}} | {{SUBJECTSPACE}}:{{{1}}} }}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{#ifexist: {{SUBJECTSPACE}}:{{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{Документировать|{{{1}}}}}
}}
}}
| {{#ifexist: {{SUBJECTPAGENAME}}/doc
| {{{{SUBJECTPAGENAME}}/doc}}
| {{Документировать|{{SUBJECTPAGENAME}}/doc}}
}}
}}
{{doc/end}}</includeonly><noinclude>
{{doc}}
</noinclude>
7298506ab2882f16fe7a52e0e080b2780b237bb9
Шаблон:Скрытый блок/styles.css
10
44
98
2025-01-10T09:29:25Z
wikipedia, ruwikipedia>Wikisaurus
0
[[Обсуждение шаблона:Скрытый блок#Убрать правило о размере шрифта в 95%]]
text
text/plain
.ts-Скрытый_блок {
margin: 0;
overflow: hidden;
border-collapse: collapse;
box-sizing: border-box;
}
.ts-Скрытый_блок-title {
text-align: center;
font-weight: bold;
line-height: 1.6em;
min-height: 1.2em;
}
.ts-Скрытый_блок .mw-collapsible-content {
overflow-x: auto;
overflow-y: hidden;
clear: both;
}
.ts-Скрытый_блок::before,
.ts-Скрытый_блок .mw-collapsible-toggle {
padding-top: .1em;
width: 6em;
font-weight: normal;
font-size: calc(90% / 0.95);
}
.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
float: right;
text-align: right;
}
.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
float: left;
text-align: left;
}
.ts-Скрытый_блок-gray {
padding: 2px;
border: 1px solid var(--border-color-base, #a2a9b1);
}
.ts-Скрытый_блок-transparent {
border: none;
}
.ts-Скрытый_блок-gray .ts-Скрытый_блок-title {
background: var(--background-color-neutral, #eaecf0);
padding: .1em 6em;
padding-right: 0;
}
.ts-Скрытый_блок-transparent .ts-Скрытый_блок-title {
background: transparent;
padding: .1em 5.5em;
padding-right: 0;
}
.ts-Скрытый_блок-gray .mw-collapsible-content {
padding: .25em 1em;
}
.ts-Скрытый_блок-transparent .mw-collapsible-content {
padding: .25em 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 1em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 6.5em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 0;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-right: 0;
}
.ts-Скрытый_блок + .ts-Скрытый_блок,
.ts-Скрытый_блок + link + .ts-Скрытый_блок {
border-top-style: hidden;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b04b4e8d09f2a95b9b1ca08e8c10ef52169ec7f1
Шаблон:Карточка/doc
10
72
154
2025-01-23T06:13:39Z
wikipedia, ruwikipedia>Mikhail Ryazanov
0
пунктуация, стилевые правки
wikitext
text/x-wiki
{{docpage}}
{{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}}
{{СИШ}}
Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]].
== Параметры ==
=== Служебные ===
; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>.
; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да».
; from: Указывается элемент Викиданных, из которого берётся информация.
=== Основные ===
; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи.
; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия.
; вверху3: Дополнительный текст, отображаемый вверху таблицы.
; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>.
; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется.
; изображение2: Дополнительное изображение.
; изображение3: Дополнительное изображение.
; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1.
; метка<sub>n</sub>: Используется для подписи текста
; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках.
; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в <tr>, таких как {{t|карточка/блок}}.
; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. Для вариантов форматирования значений, см. документацию [[Модуль:WikidataSelectors]].
; внизу
; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом).
=== Стили ===
; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}}
; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code>
; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code>
; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code>
; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание
; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение
; стиль_подписи: Применяется к подписи изображения
; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code>
; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n
; стиль_меток: Применяется к меткам
; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n
; стиль_текста: Применяется к тексту
; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n
; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''.
; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам.
== Возможности ==
=== Сдвоенные ячейки ===
Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код:
<pre><nowiki>
|текст2 = {{{параметр|}}}
|стиль_текста2 = text-align:left;
</nowiki></pre>
=== Необязательные ячейки ===
Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом:
<pre><nowiki>
|метка5 = Население
|текст5 = {{{население|}}}
</nowiki></pre>
Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена.
=== Необязательные заголовки ===
Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>:
<pre><nowiki>
|заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}}
|метка6 = Содержимое
|текст6 = {{{содержимое|}}}
|метка7 = Размещение
|текст7 = {{{размещение|}}}
</nowiki></pre>
Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN.
{|
|-
|<pre><nowiki>
|заголовок1 = {{{заголовок1|}}}
|метка1 = {{{метка1|}}}
|текст1 = {{{текст1|}}}
</nowiki></pre>
|}
{|
|-
|<pre><nowiki>
|заголовок1 = заголовок_текст
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
! заголовок_текст
|}
|<pre><nowiki>
|заголовок1 =
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
| метка_текст|| текст_текст
|}
|}
=== Оформление параметров ===
Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён:
<pre><nowiki>
|метка6 = Масса
|текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}}
</nowiki></pre>
А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например:
<pre><nowiki>
|метка6 = Раса
|текст6 = {{#switch:{{{раса|}}}
|Европеоиды = [[Европеоидная раса|Европеоиды]]
|Негроиды = [[Негроидная раса|Негроиды]]
|Монголоиды = [[Монголоидная раса|Монголоиды]]
|{{{раса|}}}
}}
</nowiki></pre>
== Пустой шаблон ==
<pre>
{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху =
|вверху2 =
|изображение =
|заголовок1 =
|метка2 =
|текст2 =
|викиданные2 =
|метка3 =
|текст3 =
|викиданные3 =
|метка4 =
|текст4 =
|викиданные4 =
|метка5 =
|текст5 =
|викиданные5 =
|метка6 =
|текст6 =
|викиданные6 =
|метка7 =
|текст7 =
|викиданные7 =
|метка8 =
|текст8 =
|викиданные8 =
|метка9 =
|текст9 =
|викиданные9 =
|метка10 =
|текст10 =
|викиданные10 =
...
|меткаN =
|текстN =
|викиданныеN =
|внизу =
}}<noinclude>
{{doc}}
</noinclude></pre>
{{скрытый|Заголовок=11—20|Содержание=<pre>
|метка11 =
|текст11 =
|викиданные11 =
|метка12 =
|текст12 =
|викиданные12 =
|метка13 =
|текст13 =
|викиданные13 =
|метка14 =
|текст14 =
|викиданные14 =
|метка15 =
|текст15 =
|викиданные15 =
|метка16 =
|текст16 =
|викиданные16 =
|метка17 =
|текст17 =
|викиданные17 =
|метка18 =
|текст18 =
|викиданные18 =
|метка19 =
|текст19 =
|викиданные19 =
|метка20 =
|текст20 =
|викиданные20 =
</pre>}}
{{скрытый||Заголовок=21—30|Содержание=<pre>
|метка21 =
|текст21 =
|викиданные21 =
|метка22 =
|текст22 =
|викиданные22 =
|метка23 =
|текст23 =
|викиданные23 =
|метка24 =
|текст24 =
|викиданные24 =
|метка25 =
|текст25 =
|викиданные25 =
|метка26 =
|текст26 =
|викиданные26 =
|метка27 =
|текст27 =
|викиданные27 =
|метка28 =
|текст28 =
|викиданные28 =
|метка29 =
|текст29 =
|викиданные29 =
|метка30 =
|текст30 =
|викиданные30 =
</pre>}}
{{скрытый||Заголовок=31—40|Содержание=<pre>
|метка31 =
|текст31 =
|викиданные31 =
|метка32 =
|текст32 =
|викиданные32 =
|метка33 =
|текст33 =
|викиданные33 =
|метка34 =
|текст34 =
|викиданные34 =
|метка35 =
|текст35 =
|викиданные35 =
|метка36 =
|текст36 =
|викиданные36 =
|метка37 =
|текст37 =
|викиданные37 =
|метка38 =
|текст38 =
|викиданные38 =
|метка39 =
|текст39 =
|викиданные39 =
|метка40 =
|текст40 =
|викиданные40 =
</pre>}}
{{скрытый||Заголовок=41—50|Содержание=<pre>
|метка41 =
|текст41 =
|викиданные41 =
|метка42 =
|текст42 =
|викиданные42 =
|метка43 =
|текст43 =
|викиданные43 =
|метка44 =
|текст44 =
|викиданные44 =
|метка45 =
|текст45 =
|викиданные45 =
|метка46 =
|текст46 =
|викиданные46 =
|метка47 =
|текст47 =
|викиданные47 =
|метка48 =
|текст48 =
|викиданные48 =
|метка49 =
|текст49 =
|викиданные49 =
|метка50 =
|текст50 =
|викиданные50 =
</pre>}}
{{скрытый||Заголовок=51—60|Содержание=<pre>
|метка51 =
|текст51 =
|викиданные51 =
|метка52 =
|текст52 =
|викиданные52 =
|метка53 =
|текст53 =
|викиданные53 =
|метка54 =
|текст54 =
|викиданные54 =
|метка55 =
|текст55 =
|викиданные55 =
|метка56 =
|текст56 =
|викиданные56 =
|метка57 =
|текст57 =
|викиданные57 =
|метка58 =
|текст58 =
|викиданные58 =
|метка59 =
|текст59 =
|викиданные59 =
|метка60 =
|текст60 =
|викиданные60 =
</pre>}}
== Примерный шаблон для карточки персоны ==
<pre>{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху = {{карточка/имя|{{{имя|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}}
|изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|}}}
|викиданные1 = p1477
|метка2 = Дата рождения
|текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}}
|метка3 = Место рождения
|текст3 = {{{место рождения|}}}
|викиданные3 = p19
|метка4 = Дата смерти
|текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}}
|метка5 = Место смерти
|текст5 = {{{место смерти|}}}
|викиданные5 = p20
|метка6 = Гражданство
|текст6 = {{{гражданство|}}}
|викиданные6 = p27
|метка7 = Сценические имена / Прозвище
|текст7 = {{{прозвище|}}}
|викиданные7 = p1449
|заголовок8 = {{wikidata|p856|{{{сайт|}}}}}
|внизу = {{карточка/Викисклад|{{{викисклад|}}}}}
}}</pre>
Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом:
* <code>13.05.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* <code>12.06.1801 (31.05)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* <code>12.01.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
== Отслеживающие категории, подставляемые шаблоном ==
{{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}}
== См. также ==
* [[Википедия:Шаблоны-карточки]]
* {{t|Универсальная карточка}}
* {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке)
* [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]]
* [[Участник:Jack who built the house/alignTemplateParameters.js]]
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны-карточки|*]]
[[Категория:Шаблоны:Мета-шаблоны]]
</includeonly>
29badbe2200149ba091573e4e4e11106d20e0688
Заглавная страница
0
1
1
2025-01-31T12:36:03Z
MediaWiki default
1
Создать главную страницу
wikitext
text/x-wiki
__NOTOC__
== Добро пожаловать в {{SITENAME}}! ==
Эта главная страница была создана автоматически и, похоже, ещё не заменена.
=== Для бюрократа(-ов) этой вики ===
Здравствуйте и добро пожаловать на вашу новую вики! Благодарим Вас за выбор Miraheze в качестве хостинга, и мы надеемся, что вы будете пользоваться нашими услугами.
Вы можете сразу же начать работать над вашем вики-сайтов, как только пожелаете.
Нужна помощь? Нет проблем! Мы поможем вам с вашей вики по мере необходимости. Для того, чтобы начать, мы добавили несколько ссылок о работе с MediaWiki:
* [[mw:Special:MyLanguage/Help:Contents|Обсуждение руководства MediaWiki (например, навигация, редактирование, удаление страниц, блокирование пользователей)]]
* [[meta:Special:MyLanguage/FAQ|ЧЗВ по Miraheze]]
* [[meta:Special:MyLanguage/Request features|Запрос изменений настроек вашей вики.]] (Изменения расширений, оформления и логотипа/фавикона должны выполняться через [[Special:ManageWiki]] в вашей вики, см. [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] для получения дополнительной информации.)
==== Но, Miraheze, я всё ещё не понимаю X! ====
Что ж, это не проблема. Даже если что-то не описано в документации/ЧЗВ, мы всё равно будем рады помочь вам. Вы можете найти нас здесь:
* [[meta:Special:MyLanguage/Help center|На нашем собственном Miraheze вики]]
* На [[phorge:|Phorge]]
* На нашем [https://miraheze.org/discord Discord-сервере]
* На IRC в #miraheze в irc.libera.chat (irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze вебчат]))
=== Для посетителя этой вики ===
Здравствуйте, заглавная страница по умолчанию ещё не была заменена бюрократом(-ами) этой вики. Возможно, администрация этого сайта разрабатывает эту страницу, поэтому мы рекомендуем вам зайти чуть позже.
da708791005da529f6c1fffe139a9b3660d023e2
Файл:Logo of Aldazipedia.png
6
2
2
2025-01-31T13:30:56Z
Генерал Альдации
2
wikitext
text/x-wiki
d
3c363836cf4e16666669a25da280a1865c2d2874
Файл:Text Aldazipedia.png
6
3
3
2025-01-31T13:34:26Z
Генерал Альдации
2
wikitext
text/x-wiki
g
54fd1711209fb1c0781092374132c66e79e2241b
Заглавная страница
0
1
4
1
2025-01-31T14:13:35Z
Генерал Альдации
2
wikitext
text/x-wiki
__NOTOC__
{| class="wikitable"
|<center>[[Файл:Logo of Aldazipedia.png|безрамки|80x80пкс]] [[Файл:Text Aldazipedia.png|безрамки]]</center>
|-
|Добро пожаловать на Альдаципедию, википедию о микронации Альдация, которую
может редактировать каждый.
|-
|
=== '''О нас''' ===
|-
|'''[[Альдация]]''' (также '''Республика Альдация''') является суверенной микронацией на
небольшой территории в Псковской области. Мы были образованы на закате
января - 31 января 2025 года подписали [[Декларация об образовании Альдации|декларацию об образовании Альдации]].
Наша идеология - социал-демократия, наш генерал - [[Роман Берестнёв]].
<center><big>''[[Альдация будет свободной|Альдация будет свободной!]]''</big></center>
|}
089275caee1ad57ee9712ddcce3db8a64b4dd6a2
5
4
2025-01-31T14:14:02Z
Генерал Альдации
2
wikitext
text/x-wiki
__NOTOC__
<center>
{| class="wikitable"
|<center>[[Файл:Logo of Aldazipedia.png|безрамки|80x80пкс]] [[Файл:Text Aldazipedia.png|безрамки]]</center>
|-
|Добро пожаловать на Альдаципедию, википедию о микронации Альдация, которую
может редактировать каждый.
|-
|
=== '''О нас''' ===
|-
|'''[[Альдация]]''' (также '''Республика Альдация''') является суверенной микронацией на
небольшой территории в Псковской области. Мы были образованы на закате
января - 31 января 2025 года подписали [[Декларация об образовании Альдации|декларацию об образовании Альдации]].
Наша идеология - социал-демократия, наш генерал - [[Роман Берестнёв]].
<center><big>''[[Альдация будет свободной|Альдация будет свободной!]]''</big></center>
|}
4f6d726798524c1f4c637e1334f0fa76c7e3e89b
6
5
2025-01-31T14:14:12Z
Генерал Альдации
2
Защитил страницу [[Заглавная страница]] ([Редактирование=Разрешено только администраторам] (бессрочно) [Переименование=Разрешено только администраторам] (бессрочно))
wikitext
text/x-wiki
__NOTOC__
<center>
{| class="wikitable"
|<center>[[Файл:Logo of Aldazipedia.png|безрамки|80x80пкс]] [[Файл:Text Aldazipedia.png|безрамки]]</center>
|-
|Добро пожаловать на Альдаципедию, википедию о микронации Альдация, которую
может редактировать каждый.
|-
|
=== '''О нас''' ===
|-
|'''[[Альдация]]''' (также '''Республика Альдация''') является суверенной микронацией на
небольшой территории в Псковской области. Мы были образованы на закате
января - 31 января 2025 года подписали [[Декларация об образовании Альдации|декларацию об образовании Альдации]].
Наша идеология - социал-демократия, наш генерал - [[Роман Берестнёв]].
<center><big>''[[Альдация будет свободной|Альдация будет свободной!]]''</big></center>
|}
4f6d726798524c1f4c637e1334f0fa76c7e3e89b
Файл:Jumpwiki.gif
6
4
7
2025-01-31T14:15:18Z
Генерал Альдации
2
wikitext
text/x-wiki
JUMP
bb0d79b578ec75d9a062b029e5cfd1928a02dd5b
MediaWiki:Common.css
8
5
8
2025-01-31T14:22:37Z
Генерал Альдации
2
Новая страница: «#footer-poweredbyico { display: none; } »
css
text/css
#footer-poweredbyico {
display: none;
}
6d7d79dea47a3e4f595e6f0cf30c879ccf587ea2
9
8
2025-01-31T14:25:08Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.floatright {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
}
.floatleft {
margin: 0 0,5em 0,5em 0;
float: left;
clear: left;
}
36136a09351355fd752e6fe2c01a734939ae0698
14
9
2025-01-31T14:38:49Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
}
1131c031351a4f7fa86ad1916c34b7e632a2ff7f
16
14
2025-01-31T14:40:17Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
311af5f84aa644ecf5f9b7180aca077a53f6b4ed
17
16
2025-01-31T14:43:30Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
.label {
font-weight: bold;
text-align: left;
}
.txt {
text-align: right;
}
062ef97c369633e82329e72015d5bb6a201f4254
19
17
2025-01-31T14:47:03Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
.label {
font-weight: bold;
text-align: left;
}
.txt {
text-align: right;
}
.label, .txt {
float: left;
width: 50%;
}
.txt {
text-align: right;
}
6f50946e107800d8a7306dc382055ca045b8c302
20
19
2025-01-31T14:48:09Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
.label {
font-weight: bold;
text-align: left;
margin-left: 5px;
margin-right: 5px;
}
.txt {
text-align: right;
margin-left: 5px;
margin-right: 5px;
}
.label, .txt {
float: left;
width: 50%;
}
.txt {
text-align: right;
}
b25d1d98ee8c41916b7dcb441fda285674add172
21
20
2025-01-31T14:49:48Z
Генерал Альдации
2
Отмена версии [[Special:Diff/20|20]], сделанной [[Special:Contributions/Генерал Альдации|Генерал Альдации]] ([[User talk:Генерал Альдации|обсуждение]])
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
.label {
font-weight: bold;
text-align: left;
}
.txt {
text-align: right;
}
.label, .txt {
float: left;
width: 50%;
}
.txt {
text-align: right;
}
6f50946e107800d8a7306dc382055ca045b8c302
22
21
2025-01-31T14:53:42Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
.label {
font-weight: bold;
text-align: left;
}
.txt {
text-align: right;
}
.label, .txt {
float: left;
width: 50%;
}
.txt {
text-align: right;
}
.imge {
max-width: 290px;
max-height: 220px;
margin: auto;
}
814c20fdc857da7c2f759b3d9cd8a5cfce16e04e
24
22
2025-01-31T15:00:28Z
Генерал Альдации
2
css
text/css
#footer-poweredbyico {
display: none;
}
.infoboxer {
margin: 0 0 0,5em 0,5em;
clear: right;
float: right;
background: #F8F9FA;
border: solid black 1px;
max-width: 600px;
}
.heading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 20px;
margin-left: 5px;
margin-right: 5px;
}
.subheading {
font-weight: bold;
text-align: center;
background-color: #CFE3FF;
font-size: 26;
margin-left: 5px;
margin-right: 5px;
}
.label {
font-weight: bold;
text-align: left;
}
.txt {
text-align: right;
}
.label, .txt {
float: left;
width: 50%;
}
.txt {
text-align: right;
}
.imge {
max-width: 290px;
max-height: 220px;
margin: auto;
}
62b8ee9c08b57ad2100a74f1f525b7e7a449231b
Шаблон:Карточка
10
8
15
2025-01-31T14:39:19Z
Генерал Альдации
2
Страница для того, чтобы брать из неё код для своего инфобокса
wikitext
text/x-wiki
<div class="infoboxer">
<div class="heading">
Заголовок
</div>
<div class="subheading">
Подзаголовок
</div>
</div>
d435773e1060972f6005a5b4127a085cbf5ff5ef
18
15
2025-01-31T14:45:02Z
Генерал Альдации
2
wikitext
text/x-wiki
<div class="infoboxer">
<div class="heading">
Заголовок
</div>
<div class="subheading">
Подзаголовок</div>
<div class="label">
ТНР
</div>
<div class="txt">
Танну-Тува
</div>
</div>
de2dac2b0de79e3bf0e3af90c31514029508ebee
23
18
2025-01-31T14:55:09Z
Генерал Альдации
2
wikitext
text/x-wiki
<div class="infoboxer">
<div class="heading">
Заголовок
</div>
<div class="imge">
[[Файл:Usovo-houses.jpg|мини|без]]
</div>
<div class="subheading">
Подзаголовок</div>
<div class="label">
ТНР
</div>
<div class="txt">
Танну-Тува
</div>
</div>
4ea1b5efbbf67793758c6577ffbe33c97442c351
25
23
2025-01-31T15:00:45Z
Генерал Альдации
2
wikitext
text/x-wiki
<div class="infoboxer">
<div class="heading">
Заголовок
</div>
<div class="imge"><center>
[[Файл:Usovo-houses.jpg|мини|без|290px|220px|СССР]]
</div>
<div class="subheading">
Подзаголовок
</center></div>
<div class="label">
ТНР
</div>
<div class="txt">
Танну-Тува
</div>
<div class="label">
ДНР
</div>
<div class="txt">
Донецкая Народная Республика
</div>
<div class="label">
А ещё
</div>
<div class="txt">
Я пират
</div>
</div>
cbaee7fd48623fae8c522a3a86afe5d1a119154c
27
25
2025-01-31T15:23:56Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<div class="infoboxer">
<div class="heading">
Заголовок
</div>
<div class="imge"><center>
[[Файл:Usovo-houses.jpg|мини|без|290px|220px|СССР]]
</div>
<div class="subheading">
Подзаголовок
</center></div>
<div class="label">
ТНР
</div>
<div class="txt">
Танну-Тува
</div>
<div class="label">
ДНР
</div>
<div class="txt">
Донецкая Народная Республика
</div>
<div class="label">
А ещё
</div>
<div class="txt">
Я пират
</div>
</div>
cbaee7fd48623fae8c522a3a86afe5d1a119154c
Модуль:Arguments
828
10
31
30
2025-01-31T15:23:57Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/песочница$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
e6be8dfccffa2057c3d50700f350d8d140c1dbf9
Модуль:TableTools
828
11
33
32
2025-01-31T15:23:57Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--[[
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should --
-- not be called directly from #invoke. --
------------------------------------------------------------------------------------
--]]
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
checkType('removeDuplicates', 1, t, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will
-- return {1, 3, 6}.
------------------------------------------------------------------------------------
--]]
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
return s
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k, v in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table
-- of subtables in the format
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }
-- Keys that don't end with an integer are stored in a subtable named "other".
-- The compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
--]]
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for k in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
else -- This will fail with table, boolean, function.
return item1 < item2
end
end
--[[
Returns a list of the keys in a table, sorted using either a default
comparison function or a custom keySort function.
]]
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })
end
local list = {}
local index = 1
for key, value in pairs(t) do
list[index] = key
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(list, keySort)
end
return list
end
--[[
Iterates through a table, with the keys sorted using the keysToList function.
If there are only numerical keys, sparseIpairs is probably more efficient.
]]
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local list = p.keysToList(t, keySort, true)
local i = 0
return function()
i = i + 1
local key = list[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
--[[
Returns true if all keys in the table are consecutive integers starting at 1.
--]]
function p.isArray(t)
checkType("isArray", 1, t, "table")
local i = 0
for k, v in pairs(t) do
i = i + 1
if t[i] == nil then
return false
end
end
return true
end
-- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 }
function p.invert(array)
checkType("invert", 1, array, "table")
local map = {}
for i, v in ipairs(array) do
map[v] = i
end
return map
end
--[[
{ "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true }
--]]
function p.listToSet(t)
checkType("listToSet", 1, t, "table")
local set = {}
for _, item in ipairs(t) do
set[item] = true
end
return set
end
--[[
Recursive deep copy function.
Preserves identities of subtables.
]]
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = deepcopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
--[[
Concatenates all values in the table that are indexed by a number, in order.
sparseConcat{ a, nil, c, d } => "acd"
sparseConcat{ nil, b, c, d } => "bcd"
]]
function p.sparseConcat(t, sep, i, j)
local list = {}
local list_i = 0
for _, v in p.sparseIpairs(t) do
list_i = list_i + 1
list[list_i] = v
end
return table.concat(list, sep, i, j)
end
--[[
-- This returns the length of a table, or the first integer key n counting from
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return
-- a different value when there are gaps in the array portion of the table.
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of
-- the number of unnamed template parameters, so use this function for
-- frame.args.
--]]
function p.length(t)
local i = 1
while t[i] ~= nil do
i = i + 1
end
return i - 1
end
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
fe918509f168332267834b3a6f5c219a9de5b2e7
Модуль:Template call code
828
12
35
34
2025-01-31T15:23:58Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName, flags)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args, flags)
end
end
--предотвращает обработку вики-текста в отображении образца
local function processText(str, nowiki)
local res = str
if nowiki then
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
end
return str
end
local function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
local function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
text = text .. ' ts-templateCallCode-weak'
end
-- |, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">|</span>'
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
if k >= params.from then
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
else -- Истинно неименованные
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
end
end
return text
end
function p._main(args, flags)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if not flags.withoutParams then
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
end
local yesno = require('Module:Yesno')
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr
local tag, style, comment, lang, sister, global, textInPlaceOfName,
namePrefix, prefix, postfix, nowiki
local spaced, from
if flags.withoutParams then
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
noLink = true
elseif v == 's' then
subst = true
elseif v == 'п' then
podst = true
elseif v == 'g' then
global = true
elseif v == 'nav' then
nav = true
elseif v == 'noredir' then
noRedirect = true
elseif v == 'u' then
ucFirst = true
elseif v == 'b' then
black = true
elseif v == 'nobr' then
nobr = true
end
end
tag = args.tag or 'span'
style = args.style
comment = args.comment
lang = args.lang
sister = args.sister
textInPlaceOfName = args.text
namePrefix = args.nameprefix
prefix = args.prefix
postfix = args.postfix
nowiki = args.nowiki
else
noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
subst = yesno(args._s, false)
podst = yesno(args['_п'], false)
global = yesno(args._g, false)
nav = yesno(args._nav, false)
noRedirect = yesno(args._noredir, false)
ucFirst = yesno(args._u, false)
black = yesno(args._b, false)
nobr = yesno(args._nobr, false)
tag = args._tag or 'span'
style = args._style
comment = args._comment
lang = args._lang
sister = args._sister
textInPlaceOfName = args._text
namePrefix = args._nameprefix
prefix = args._prefix
postfix = args._postfix
nowiki = args._nowiki
spaced = yesno(args._spaced, false)
from = (tonumber(args._from) or 2) - 1
end
global = global or name and mw.ustring.sub(name, 1, 1) == ':'
black = black or tag ~= 'span'
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if namePrefix == '' then
namePrefix = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if subst then
namePrefix = 'subst:'
elseif podst then
namePrefix = 'подст:'
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
(
(
ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="ts-templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. processText(prefix, nowiki)
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">{{'
if namePrefix then
text = text .. namePrefix
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">'
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.withoutParams then
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
nowiki = nowiki,
from = from
})
if spaced then
text = text .. ' '
end
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">}}</span>'
if postfix then
text = text .. processText(postfix, nowiki)
end
if tag then
text = text .. '</' .. tag .. '>'
end
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
function p._onlyParams(args)
local yesno = require('Module:Yesno')
return addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
nowiki = yesno(args._nowiki, false),
from = 1
})
end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')
return p
c4cde66869b509219e9bf629a766ce30ad0bdf97
Модуль:Yesno
828
13
37
36
2025-01-31T15:23:58Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
-- кириллица
or val == 'у'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
ae94e12a838e770797317ed07b57b330ffeb7658
Модуль:Template call code/styles.css
828
14
39
38
2025-01-31T15:23:58Z
Генерал Альдации
2
1 версия импортирована
text
text/plain
.ts-templateCallCode-weak {
color: #72777d;
}
.ts-templateCallCode-pipe {
margin: 0 2px;
}
.ts-templateCallCode-pipe + .ts-templateCallCode-pipe,
/* Template:Optp */
.ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child {
margin-left: 0;
}
.ts-templateCallCode-param + .ts-templateCallCode-closing {
margin-left: 2px;
}
span.ts-templateCallCode > .ts-templateCallCode-templateName a {
/* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */
padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */
position: relative;
margin: -0.5em;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b3ed166240cf28c48a58b8d992794b753b2c6ef5
Модуль:Message box
828
15
41
40
2025-01-31T15:23:58Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('mbox-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
if args.sect and args.sect ~= '' or nil then
local issue_sect = args.issue_sect
issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil
local text_sect = args.text_sect
text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil
local issues = {}
table.insert(issues, issue_sect)
table.insert(issues, text_sect)
self.issue = table.concat(issues, ' ')
else
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
if self.isSmall then
self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Conditional TemplateStyles loading
if self.base_templatestyles then
local frame = mw.getCurrentFrame()
root:wikitext(frame:extensionTag{
name = 'templatestyles',
args = { src = self.base_templatestyles },
})
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle)
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.fix and (' ' .. self.fix) or nil)
:wikitext(self.talk and (' ' .. self.talk) or nil)
end
if self.textsmall or self.fix or self.talk then
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
else
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
end
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f2539b657a9cdadde7c0dd5ad270d3095b2bdd54
Модуль:Category handler
828
16
43
42
2025-01-31T15:23:59Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Модуль:Calendar
828
17
45
44
2025-01-31T15:23:59Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
-- Необходимые модули и переменные
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local mwlang = mw.getContentLanguage()
local err = "―" -- NthDay nil result
local tCon = table.concat
-- 00) Блок многократно используемых списков
local bool_to_number={ [true]=1, [false]=0 }
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"}}
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
-- duplicates:
-- AST, BST, CST, ECT, IST, MST, PST, SST,
local known_tzs = {
ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00',
AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00',
AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00',
BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00',
BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30',
CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45',
CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00',
COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00',
CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00',
ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00',
EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00',
GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00',
GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00',
HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30',
IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00',
LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30',
MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30',
MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30',
NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00',
SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00',
SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00',
UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00',
WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00',
-- US Millitary (for RFC-822)
Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
}
local category = {
["no_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->",
["incomplete_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->",
["without_verification"]=
"<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->",
["erroneous_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->"
}
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением
local e = {
["start"]="<span class=error>Ошибка: ",
["ending"]=".</span>",
["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами",
["no_valid_date"]="дата «%s» не является корректной",
["wrong_jd"]="юлианская дата %s вне диапазона",
["no_data"]="нет входящих данных",
["too_many_arguments"]="ожидается менее %i аргументов",
["too_little_arguments"]="ожидается более %i аргументов",
["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница",
["unknown_param"]="параметр %s неизвестен",
["unknown_error"]="неизвестная ошибка",
["tech_error"]="ошибка в функции %s",
["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД"
-- [""]="",
}
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
local pattern = { -- для распознавания дат, переданных одним строчным параметром
{"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd
{"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy
{"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy
{"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm
{"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y
{"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y
{"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y
}
local time_units = {"year","month","day"} --не используется
--[[ local time_units = {"second", "minute", "hour",
"day_of_month", "day_of_week", "day_of_year",
"week", "month", "year", "year_of_century", "century"} ]]--
-- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов
local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"}
local month_lang = {
["ru_G"] = {"января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря"},
["ru_N"] = {"январь","февраль","март","апрель","май","июнь",
"июль","август","сентябрь","октябрь","ноябрь","декабрь"},
["en"] = {"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"},
["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"},
["de"] = {"januar", "februar", "märz", "april", "mai", "juni",
"juli", "august", "september", "oktober", "november", "dezember"},
["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"}
}
-- заполняется автоматически
local reverse_month_lang = {}
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)
local reverse_table = function (strait_table)
local reversed_table = {}
for k,v in pairs(strait_table) do
reversed_table[v] = k
end
return reversed_table
end
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат
local filling_months = function (mnlang, month_lang)
for i=1, #mnlang do
reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]])
end
end
-- 10) Блок общих функций
local function trim(str)
if not str then return nil
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
end
local function purif(str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter?
end
local function is(str)
if (not str) or (str == "") then return false
else return yesno(str,false)
end
end
local function init(num)
local output = {}
for i=1,num do
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
end
return unpack(output)
end
local function isyear(tbl)
if type(tbl) ~= 'table' then return false
elseif not tbl["year"] then return false
elseif type(tbl["year"]) == 'number' then return true
else return false
end
end
local function inbord(val, down, up)
return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)
end
local function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local inlist = function ( var, list )
local n = #list
local inlist = false
for i=1,n do
if var == list[i] then inlist = true end
end
return inlist
end
-- 20) Блок общих проверочных функций, связанных с датами
local function unwarp(tbl)
if not tbl then return ""
elseif type(tbl) ~= "table" then return tbl
elseif (tbl.day or tbl.month or tbl.year) then
return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?")
else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?")
end
end
local function leap_year(y,jul)
if (not y) or (type(y) ~= "number")
then return false
elseif (y % 4) ~= 0
then return false
elseif not jul and (y % 100 == 0 and y % 400 ~= 0)
then return false
else return true
end
end
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей
local function month_end_day (month,year,is_julian)
local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой
if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil
elseif month ~= 2 or not year then return month_end_day[month]
elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29
elseif month == 2 then return 28
else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях
end
end
local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year
if not chain then return false
elseif (not type(chain) == "table")
or (not inbord(chain.year,-9999,9999))
or (not inbord(chain.month,1,12))
or (not inbord(chain.day,1,31))
or chain.day > monthd[chain.month]
-- or chain.year == 0
then return false
elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul)
then return false
else return true end
-- check for other calendars needed?
end
local function ispartdate ( chain )
if not chain then return false
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
or inbord(chain.month,1,12)
or inbord(chain.day,1,31)) then return true
else return false
end
-- partial date
-- more detailed check for 31.02.0000 needed
-- check for other calendars needed
end
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
local function partdist(date1,date2)
local mont, dist = 0, 0
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
-- нужна доп. проверка частичных дат на корректность
if (inbord(d1m,1,12) or inbord(d2m,1,12))
and (d1m == "" or d2m == "") then
mont = purif(date1["month"] or date2["month"])
d1m, d2m = mont, mont
end
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
if d2m == d1m
then dist = d2d - d1d
else dist = monthd[d1m] - d1d + d2d
end
return dist
else return math.huge
end
end
local function dmdist(d1,d2)
local p1,p2 = math.huge,math.huge
if not not partdist(d1,d2) then
p1=partdist(d1,d2)
end
if not not partdist(d2,d1) then
p1=partdist(d2,d1)
end
-- if (not p1) or (not p2) then
-- return (p1 or "") .. (p2 or "")
-- else
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
-- end
end
-- 30) Блок функций для обработки ввода-вывода дат
local function undate(tbl)
if not tbl then return ""
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
end
end
-- функция для нормализации значений дат и перевода месяцев в числа
local function numerize(str)
if type(str) == "number" then
return math.floor(str)
elseif str == "" or str == nil or type(str) ~= "string" then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
for i=1, #mnlang do
if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then
return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)]
end
end
end
end
-- функция распознавания даты, переданной одной строкой
local function parse_date(date_string)
if type(date_string) ~= "string" or date_string == "" then return nil end
local out_date_str = {"","",""}
local error_data = {}
for i=1, #pattern do
local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1])
if (result_1 or "") > "" then
out_date_str[pattern[i].order[1]] = result_1
out_date_str[pattern[i].order[2]] = result_2
if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end
-- mw.log("Паттерн " .. i .. ", строка: " .. date_string)
break
end
end
local date = {
["day"] =numerize(out_date_str[1]),
["month"]=numerize(out_date_str[2]),
["year"] =numerize(out_date_str[3])}
return date --, error_data
end
----[[ УСТАРЕЛО ]]----
local numstr2date = function(numstr)
local format = "Y-m-d"
local iso_date = mwlang:formatDate(format,numstr)
local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
return dateout
end
--local numstr2date = function(numstr)
-- local nums = {}
-- local dateout = {}
-- for num in string.gmatch(numstr,"(%d+)") do
-- table.insert(nums,purif(num))
-- end
-- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
-- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
-- elseif not inbord(nums[3],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- elseif not inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
-- elseif inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- else
-- local mwlang = mw.getContentLanguage()
-- implement mwlang:formatDate(format,datein,true) here
-- return error("Не распознано " .. numstr .. " как дата")
-- end
-- return dateout
--end
local function year2lang(numyear,yearmark,wiki)
if not numyear then return "" end
if not yearmark then yearmark = "" end
local output = ""
local bcmark = " до н. э."
if numyear > 0 then bcmark = ""
else numyear = 1 - numyear end
if wiki then
-- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'})
else
output = tCon({numyear, " ", yearmark, bcmark})
end
return trim(output)
end
local function day2lang(datein,wikidate,wiki,inner_brt)
-- if not isdate(wikidate) then wiki = false end
if not ispartdate(datein) then return "" end
local dm_separ, output = "", nil
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not datein.month) then datein.month = "" end
if (not datein.day) then datein.day = "" end
local monlan = monthlang[datein.month] or ""
if wiki and not inner_brt then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan, "]]"})
elseif wiki then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan})
else
output = tCon({datein.day, dm_separ, monlan})
end
return trim(output)
end
local function triple_txt2date(d,m,y)
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
-- mw.ustring.match((m or ""),"(%a+)")
local msg = ""
local year = purif((y or "-"):match("(%d+)"))
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
local day = purif((d or "-"):match("(%d+)"))
if not month then
msg = category.incomplete_parameters
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
end
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
msg = category.incomplete_parameters
day = purif(m:match("(%d+)") or "")
end
if not year then
msg = category.incomplete_parameters
year = purif(string.match(m or "","(%d+)") or "")
end
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
return dateout
end
local function glue(d1,m1,y1,d2,m2,y2)
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
return category.incomplete_parameters end
local gd,gm,gy,jd,jm,jy =
(d1 or ""),
(m1 or ""),
(y1 or ""),
(d2 or ""),
(m2 or ""),
(y2 or "")
--mw.log(tCon({gd,gm,gy,jd,jm,jy}))
local gm_sep = {" [["," год|","]]"}
if (not gy) or (gy == "") then gm_sep = {"","",""} end
return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""),
gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters})
end
-- добавить отображение без года
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
local msg = ""
msg = (jdate.msg or "") .. (gdate.msg or "")
local cd = {}
local jd = shallowcopy(jdate)
local gd = shallowcopy(gdate)
local left = "("
local right = ")"
if sq_brts then
left = "["
right = "]"
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
if jd.year == gd.year then
cd.year = gd.year
gd.year, jd.year = nil, nil
end
if jd.month == gd.month then
cd.month = gd.month
gd.month, jd.month = nil, nil
end
if (not not cd.month) and wm then
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
local function gri2jd( datein )
if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1931076.5, 5373557.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2jul( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local c = jd + 32082
local d = math.floor((4*c + 3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e + 2)/153)
local year_out = d - 4800 + math.floor(m/10)
local month_out = m + 3 - 12*math.floor(m/10)
local day_out = e - math.floor((153*m + 2)/5) + 1
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function jul2jd( datein )
if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - 32083
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1930999.5, 5373484.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2gri( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local a = jd + 32044
local b = math.floor((4*a + 3) / 146097)
local c = a - math.floor(146097*b/4)
local d = math.floor((4*c+3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e+2)/153)
local day_out = e - math.floor((153*m+2)/5)+1
local month_out = m + 3 - 12*math.floor(m/10)
local year_out = 100*b + d - 4800 + math.floor(m/10)
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function astroyear(num, bc)
if not num then return error()
elseif type(num) ~= "number" then return error()
end
if num < 1 then return num end
if not bc then return num
else return 1 - num
end
end
local function recalc(datein,calend)
if inlist(calend,params[1]) then
return jd2jul(gri2jd(datein)), datein
elseif inlist(calend,params[2]) then
return datein, jd2gri(jul2jd(datein))
else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," "))
end
end
-- 50) Функции для обработки UTC
local function utc(str,margin)
local d = 1
local dchar = "+"
local beginning = "[[UTC"
local ending = "]]"
local cat = ""
local nums = {}
local hmarg, timedec = 0, 0
local mmarg = "00"
local output = ""
-- checking type of input
if not margin then margin = 0
elseif type(tonumber(margin)) ~= 'number' then
output = "Can't shift by " .. margin
error(output)
end
if type(str) ~= 'string' then
error("Нет входящей строки")
elseif str:byte(1) == 43 then
elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]"
elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1
else
error(string.char(str:byte(1)) .. " недопустимый первый символ")
end
-- parsing input
for num in string.gmatch(str,"(%d+)") do
table.insert(nums,purif(num))
end
if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums)
elseif #nums == 0 then error("Необходимо что-то ввести")
elseif #nums == 1 then
if inbord(nums[1],0,14) then timedec = d*nums[1] + margin
else error("Только часы от -14 до 14") end
elseif #nums == 2 then
if not inbord(nums[1],0,14) then error("Только часы от -14 до 14")
elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59")
else
timedec = d*(nums[1] + nums[2]/60) + margin
end
end
if tonumber(timedec) == purif(timedec) then hmarg = timedec
else
local h, m = math.modf(math.abs(timedec))
hmarg = h
mmarg = math.floor(m*60)
end
if timedec == 0 then
dchar = "±"
elseif timedec > 0 then
elseif timedec < 0 then
dchar = "−"
end
-- output
output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat
return output
end
-- 60) Блок функций ввода-вывода
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num, wday, mont, yea, format =
purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
if not format then format = "%d.%m.%y" end
if not inbord(num,-5,5) then
return error("The number must be between -5 and 5")
elseif num == 0 then
return error("The number must not be zero") end
if not inbord(wday,0,6) then
return error("The day of the week must be between 0 and 6") end
if not inbord(mont,1,12) then
return error("The month must be between 1 and 12") end
if not inbord(yea,0,9999) then
return error("Wrong year number") end
if inbord(num,1,5) then
local m_start = os.time{year=yea, month=mont, day=1, hour=0}
local m_wds = tonumber(os.date("%w", m_start))
local start_shift = (
(num - bool_to_number[wday >= m_wds]) * 7
- (m_wds - wday)
) * 24 * 60 * 60
local tim = m_start + start_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
elseif inbord(num,-5,-1) then
local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
local m_wde = tonumber(os.date("%w", m_end))
local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
+ (m_wde - wday)) * 24 * 60 * 60
local tim = m_end - end_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
end
end
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
function p.ToIso( frame )
local args = getArgs(frame, { frameOnly = true })
local datein = args[1]
-- инициализация, заполнение обратных таблиц, копирование параметров
filling_months(mnlang, month_lang)
-- парсинг входящей даты по шаблону
local date = parse_date(datein)
if not (type(date.year) == 'number') then
return ("Wrong year: " .. unwarp(date))
end
if not (1 <= date.month and date.month <= 12) then
return ("Wrong month: " .. unwarp(date))
end
if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then
return ("Wrong day: " .. unwarp(date))
end
local timedate = os.time{year=date.year, month=date.month, day=date.day}
local date = os.date("%Y-%m-%d", timedate)
return date
end
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}})
function p.BoxDate( frame )
local args = getArgs(frame, { frameOnly = true })
local txtDateIn, strFormat = args[1], args[2]
local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
function p.bxDate( txtDateIn , strFormat, params ) -- к отладке
local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""}
strFormat = strFormat or "j xg Y"
-- заглушка - таблица параметров на будущее
params = params or {}
if not txtDateIn then
status.errorText = e.no_data
status.errorCat = category.no_parameters
status.brk = true
else
-- заполнение служебных таблиц
filling_months(mnlang, month_lang)
end
if not status.brk then
-- парсинг входящей даты по шаблону
date = parse_date(txtDateIn)
-- заменить сообщения об ошибках на списочные
if not (date.year and type(date.year) == 'number') then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not inbord(date.month,1,12) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not date.day and string.find(strFormat,"[dDjlNwzW]") then
strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]",""))
elseif not date.day then
elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
end
if not status.brk then
txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true)
end
return txtDateOut, date, status
end
function p.ToDate( frame ) -- возможно неиспользуемая
local args = getArgs(frame, { frameOnly = true })
local mwlang = mw.getContentLanguage()
local datein = args[1]
local format = "j xg Y"
if not string.match(datein, "%p") then return datein
elseif not args[2] then
else format = args[2]
end
return mwlang:formatDate(format,datein,true)
end
-- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}})
function p.unitime( frame )
local args = getArgs(frame, { frameOnly = true })
local DST = 0
if not args[2] then
else DST = 1 end
local utcin = ""
local input = args[1]
if not input then return "" end
if inlist(input:upper(),tzs_names) then
utcin = known_tzs[input:upper()]
elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
utcin = string.sub(input,4)
else
if string.sub(input,1,1) == '['
or string.sub(input,1,1) == '{'
or string.sub(input,1,1):upper() == 'U'
or string.sub(input,1,1):upper() == 'M' then
return input
-- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or
-- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then
-- return input
else utcin = input end
end
-- elseif string.sub(input,1,3) ~= "−" then utcin = input
-- or not (not input:find("[А-я]")) при наличии в строке юникода не работает
local output = ""
if DST == 0 then output = utc(utcin)
else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST)
end
return output
end
-- УСТАРЕЛО
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
function p.OldDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local gdate, jdate = {}, {}
local strin = args[1]
local cal = args[2]:lower() or "г"
local bc = is(args["bc"])
local wd = is(args["wd"])
local wm = is(args["wm"])
local wy = is(args["wy"])
if not wd then wm = false end
local sq_brts = is(args["sq_brts"])
local yearmark = "года"
if yesno(args["yearmark"]) then
elseif yesno(args["yearmark"]) == false then yearmark = ""
else yearmark = trim(args["yearmark"]) or "года" end
-- local infocard = is(args["infocard"])
-- local catName = args["catName"] or false
local datein = numstr2date(strin)
datein.year = astroyear(datein.year, bc)
jdate, gdate = recalc(datein,cal)
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
function p.NewDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local strin = args[1]
local year, month, day
if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then
year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" )
elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then
year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" )
elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then
day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" )
elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then
day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" )
end
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
end
local cal = "г"
if (not args[2]) or (args[2] == "") then cal = "г"
else cal = args[2]:lower() end
local bc,wd,wm,wy,sq_brts =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"])
year = astroyear(purif(year),bc)
local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
local jdate, gdate = recalc(datein,cal)
local yearmark = "года"
local ym = args["yearmark"] or ""
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
function p.Test( frame )
local args = getArgs(frame, { frameOnly = true })
-- необходима проверка и замена nil на " "
--[[mw.log((args[1] or "") .. " " ..
(args[2] or "") .. " " ..
(args[3] or "") .. " " ..
(args[4] or "") .. " " ..
(args[5] or "") .. " " ..
(args[6] or "")) ]]--
local ingdate = triple_txt2date(args[1],args[2],args[3])
local injdate = triple_txt2date(args[4],args[5],args[6])
local j1date, g1date, j2date, g2date = init(4)
mw.log("ingdate-".. (undate(ingdate) or ""))
mw.log("injdate-".. (undate(injdate) or ""))
local bc,wd,wm,wy,sq_brts,ny =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"]),
is(args["ny"])
-- подавление формата для локальных тестов
local wd, wm, wy = true, true, true
local yearmark = "года"
local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
-- mw.log("ym " .. ym)
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
if isdate(ingdate) or isdate(injdate) then
if isdate(ingdate) then
j1date, g1date = recalc(ingdate,"g")
ingdate["full"] = true
end
if isdate(injdate) then
j2date, g2date = recalc(injdate,"j")
injdate["full"] = true
end
if ispartdate(ingdate) and ispartdate(injdate) then
mw.log("📏 " .. dmdist(ingdate,injdate))
mw.log("📏 " .. dmdist(j1date,g1date))
mw.log("📏 " .. dmdist(j2date,g2date))
mw.log("📏 " .. dmdist(ingdate,g1date))
mw.log("📏 " .. dmdist(injdate,j2date))
end
end
if ny then
if isyear(j1date) then
else j1date["year"] = "" end
if isyear(j2date) == nil then
else j2date["year"] = "" end
if isyear(g1date) == nil then
else g1date["year"] = "" end
if isyear(g2date) == nil then
else g2date["year"] = "" end
end
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
if ((j1date.year == j2date.year)
and (j1date.month == j2date.month)
and (j1date.day == j2date.day)) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
else
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- категория (предположительная разница в днях) и частичный вывод
end
elseif isdate(j1date) and isdate(g1date) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif isdate(j2date) and isdate(g2date) then
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- частичный или полный вывод, категория
else
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
return err .. category.incomplete_parameters
end
end
return p
a4a91f134ad3e3b246b3a6681a4ae438da766df4
Модуль:Message box/configuration
828
18
47
46
2025-01-31T15:23:59Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]',
templatestyles = 'Module:Message box/ambox.css',
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/cmbox.css',
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/fmbox.css',
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов',
templatestyles = 'Module:Message box/imbox.css',
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/ombox.css',
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений',
templatestyles = 'Module:Message box/tmbox.css',
}
}
2c0750ec1561e8ec25c0988c411f3c69e4957483
Модуль:Category handler/data
828
19
49
48
2025-01-31T15:24:00Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Модуль:Category handler/config
828
20
51
50
2025-01-31T15:24:00Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Модуль:Category handler/shared
828
21
53
52
2025-01-31T15:24:02Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Модуль:Category handler/blacklist
828
22
55
54
2025-01-31T15:24:02Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template messages/.*$',
'/[aA]rchive' -- Don't categorise archives.
}
c84948ad9808d5d323408d5d10d5652f748a0550
Модуль:Namespace detect/data
828
23
57
56
2025-01-31T15:24:02Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Модуль:Namespace detect/config
828
24
59
58
2025-01-31T15:24:03Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Шаблон:Yesno
10
25
61
60
2025-01-31T15:24:03Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }}
|no
|n
|нет
|false
|0 = {{{no|<!-- null -->}}}
| = {{{blank|{{{no|<!-- null -->}}}}}}
|¬ = {{{¬|}}}
|yes
|y
|да
|true
|1 = {{{yes|yes}}}
|#default = {{{def|{{{yes|yes}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4e236854c477d07a225c2ab6c016c389b133e8d3
Шаблон:Карточка/внизу
10
26
63
62
2025-01-31T15:24:03Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude>
{{doc}}
</noinclude>
169fb2d10b0847c2fd677eda9f159ba99025198f
Модуль:String
828
27
65
64
2025-01-31T15:24:04Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
subcount
This function returns the count of substring in source string.
Usage:
{{#invoke:String|subcount|source_string|substring|plain_flag}}
OR
{{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
plain: A flag indicating that the substring should be understood as plain
text. Defaults to true.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.subcount( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} );
local s = new_args['s'] or '';
local plain_flag = str._getBoolean( new_args['plain'] or true );
local pattern = new_args['pattern'] or '';
if s == '' or pattern == '' then
return 0;
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local _, count = mw.ustring.gsub(s, pattern, "")
return count;
end
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local s = new_args['s'] or '';
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local s = new_args['s'] or '';
local i = tonumber( new_args['i'] ) or 1;
local j = tonumber( new_args['j'] ) or -1;
local len = mw.ustring.len( s );
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1;
end
if j < 0 then
j = len + j + 1;
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'Значение индекса подстроки выходит за допустимые границы' );
end
if j < i then
return str._error( 'Неверный порядок индексов подстроки' );
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local s = new_args['s'] or '';
local start = tonumber( new_args['start'] ) or 1;
local plain_flag = str._getBoolean( new_args['plain'] or false );
local pattern = new_args['pattern'] or '';
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local nomatch = new_args['nomatch'];
if s == '' then
return str._error( 'Пустая строка поиска' );
end
if pattern == '' then
return str._error( 'Пустой шаблон поиска' );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Индекс начала поиска выходит за допустимые границы' );
end
if match_index == 0 then
return str._error( 'Индекс совпадения выходит за допустимые границы' );
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start );
end
local iterator = mw.ustring.gmatch(s, pattern);
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1;
if match_index == 0 then
result = w;
break;
end
end
else
-- Reverse search
local result_table = {};
local count = 1;
for w in iterator do
result_table[count] = w;
count = count + 1;
end
result = result_table[ count + match_index ];
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Совпадение не найдено' );
else
return nomatch;
end
else
return result;
end
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local target_str = new_args['target'] or '';
local pos = tonumber( new_args['pos'] ) or 0;
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'Значение индекса строки выходит за допустимые границы' );
end
return mw.ustring.sub( target_str, pos, pos );
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} );
local source_str = new_args['source'] or '';
local target_str = new_args['target'] or '';
if target_str == '' then
return 1;
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['target'] or '';
local start_pos = tonumber(new_args['start']) or 1;
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return 0;
end
plain = str._getBoolean( plain );
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['pattern'] or '';
local replace = new_args['replace'] or '';
local count = tonumber( new_args['count'] );
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return source_str;
end
plain = str._getBoolean( plain );
if plain then
pattern = str._escapePattern( pattern );
replace = string.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences.
end
local result;
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count );
else
result = mw.ustring.gsub( source_str, pattern, replace );
end
return result;
end
--[[
This function adds support for escaping parts of the patterns when using [plain=false].
]]
function str.escape( frame )
local new_args = str._getParameters( frame.args, {'pattern' } );
local pattern = new_args['pattern'] or '';
local result = '';
result = str._escapePattern( pattern );
return result;
end
--[[
Internal compare string function
]]
function str._strcmp(a , b)
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
local c2 = s2c();
if c1 == nil then
if c2 == nil then
return 0
else
return -1
end
else
if c2 ~= nil then
if c1 ~= c2 then
return c1 < c2 and -1 or 1
end
else
return 1
end
end
end
return 0
end
--[[
compare
This function compare two UTF-8 strings
Usage:
{{#invoke:String|compare|str1|str2}}
Returns:
0 - if strings are equal
1 - if st1 > str2
-1 - if str1 < str2
]]
function str.compare(frame)
local str1 = frame.args[1] or '';
local str2 = frame.args[2] or '';
return str._strcmp(str1 , str2)
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Страницы с ошибками модуля String';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if str._getBoolean(ignore_errors) then
return '';
end
local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>';
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Категория:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'Логическое значение не найдено' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return ( string.gsub( pattern_str, "[%(%)%.%%%+%-%*%?%[%^%$%]]", "%%%0" ) )
end
return str
2c7347f1dafbbc0efc196c148a1f81e7b82420dc
Модуль:Infobox
828
28
67
66
2025-01-31T15:24:04Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {};
local yesno = require('Module:Yesno')
local function _renderLine( frame, args, i )
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then
return ''
elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' );
local class = ( args[ 'класс' .. i ] or '' );
return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' ..
args[ 'заголовок' .. i ] ..
'</th>\n</tr>';
end
if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then
return args[ 'блок' .. i ];
end
local text = args[ 'текст' .. i ] or '';
if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then
text = frame:expandTemplate{ title = 'Wikidata', args = {
args[ 'викиданные' .. i ],
text,
from = args[ 'from' ] or ''
} };
end
if text ~= '' then
local label = args[ 'метка' .. i ] or '';
local class = args[ 'класс' .. i ] or '';
if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then
class = class .. ' plainlist';
end
if class ~= '' then
class = ' class="' .. class .. '"';
end
local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' );
if label == '' then
style = 'text-align:center;' .. style;
end
if style ~= '' then
style = ' style="' .. style .. '"';
end
if label ~= '' then
local labelClass = args[ 'класс_меток' ] or '';
if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then
labelClass = labelClass .. ' plainlist';
end
if labelClass ~= '' then
labelClass = ' class="' .. labelClass .. '"';
end
local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' );
if labelStyle ~= '' then
labelStyle = ' style="' .. labelStyle .. '"';
end
return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' ..
'\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '';
end
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.renderLine( frame )
local args = frame:getParent().args;
return _renderLine(frame, args, '')
end
function p.renderLines( frame )
local args = frame:getParent().args;
local res = ''
local header, text = '', ''
local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false)
for i = 1, maxNumber(args) do
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
header, text = _renderLine(frame, args, i), ''
else
text = text .. _renderLine(frame, args, i)
end
end
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
return res
end
return p;
c830c997bd3d15923f347277e3b0ae71b7ba917e
Модуль:Transclude
828
29
69
68
2025-01-31T15:24:05Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p={}
-- Вызывает внутренний шаблон с аргументами объемлющего шаблона
function p.call(frame)
local template = frame.args[1]
local args = frame:getParent().args
return frame:expandTemplate{ title=template, args=args }
end
-- Общая реализация для forall и call
local function forallImpl(args, separator, conjunction, func)
-- нумерованные ключи из args
local keys = {}
-- перебор в произвольном порядке, даже для нумерованных ключей
for key, value in pairs(args) do
if type(key) == 'number' and value and value ~= '' then
table.insert(keys, key)
end
end
table.sort(keys)
local results = {}
for _, key in ipairs(keys) do
local value = func(args[key])
table.insert(results, value)
end
return mw.text.listToText(results, separator, conjunction)
end
-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному
function p.forall(frame)
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local args = frame:getParent().args
local func = function(value)
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame?
end
return forallImpl(args, separator, conjunction, func)
end
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку
function p.join(frame)
local separator = frame.args[1] or ''
local conjunction = frame.args[2] or separator
local args = frame:getParent().args
local func = function(value)
return value
end
return forallImpl(args, separator, conjunction, func)
end
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами
local function deleteDuplicates(args)
local res = {}
for key, value in pairs(args) do
if args[key+1] ~= value then
table.insert(res, value)
end
end
return res
end
-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона
function p.npc(frame)
local args = frame:getParent().args
local templateFrame = frame:getParent()
local template = frame.args[1]
-- определение, блоки аргументов с какими номерами нужны:
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок
local nums = {}
for key, _ in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- учитывать "параметр12", только если задано "параметр"
if num and frame.args[main] then
table.insert(nums, num)
end
end
table.sort(nums)
nums = deleteDuplicates(nums)
-- проходить по нужным номерам блоков по возрастанию и однократно
-- подставлять в шаблон:
-- 1. общие аргументы данного модуля
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок
local results = {}
for _, blockNum in ipairs(nums) do
-- общие аргументы модуля, которые передаются в каждый блок
local blockArgs = mw.clone(frame.args)
-- metatable ломает expandTemplate
setmetatable(blockArgs, nil)
for key, value in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля
if blockNum == num and frame.args[main] then
blockArgs[main] = value
end
end
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs }
table.insert(results, blockText)
end
return table.concat(results)
end
-- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2].
function p.cycle(f)
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline';
local sep='';
if op == 'newline' then
sep='\n';
end
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
s=tonumber(s);
local acr={};
if not s then error('Начало цикла «'..s..'» — не число') end
local function dc(order)
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
if order == 'desc' then
s=s-1;
else
s=s+1;
end
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
if fh > s then
while s<=fh do dc('asc') end
else
while s>=fh do dc('desc') end
end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
else
while dc('asc') do end
end
return table.concat(acr, sep)
end
return p
c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59
Шаблон:Replace
10
30
71
70
2025-01-31T15:24:05Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude>
{{doc}}
</noinclude>
7752c3c70ae8c46a89a0808aa282956866dbba5b
Шаблон:Str left
10
31
73
72
2025-01-31T15:24:05Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude>
{{doc}}
</noinclude>
c1f57b63826f4d455dcaec8d2c24a2b8268f42ec
Шаблон:Join
10
32
75
74
2025-01-31T15:24:06Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude>
{{doc}}
<!-- Категории — на подстраницу /doc, интервики — в Викиданные. -->
</noinclude>
92bb17b5322d3ae0ceab93d4dad3d31810d47eb0
Модуль:Navbox
828
33
77
76
2025-01-31T15:24:07Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--
-- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}.
-- Основной объём кода заимствован из английского Module:Navbox.
--
local p = {}
local navbar = require('Module:Navbar')._ruwikiNavbar
local getArgs -- lazily initialized
local yesno -- lazily initialized
local styleratio
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
-- общие параметры для всех шаблонов
local commonAliases = {
name = {'name', 'имя'},
navigation = {'navigation', 'навигация'},
navbar = {'navbar', 'ссылка_на_просмотр'},
state = {'state'},
orphan = {'orphan'},
tracking = {'tracking'},
border = {'border', 1},
title = {'title', 'заголовок'},
titlegroup = {'titlegroup'},
above = {'above', 'вверху'},
image = {'image', 'изображение'},
imageleft = {'imageleft', 'изображение2', 'изображение_слева'},
below = {'below', 'внизу'},
bodyclass = {'bodyclass', 'класс_тела'},
titleclass = {'titleclass', 'класс_заголовка'},
titlegroupclass = {'titlegroupclass'},
aboveclass = {'aboveclass', 'класс_вверху'},
belowclass = {'belowclass', 'класс_внизу'},
groupclass = {'groupclass', 'класс_групп'},
listclass = {'listclass', 'класс_списков'},
imageclass = {'imageclass', 'класс_изображения'},
basestyle = {'basestyle', 'стиль', 'стиль_базовый'},
bodystyle = {'style', 'bodystyle', 'стиль_тела'},
titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'},
titlegroupstyle = {'titlegroupstyle'},
innerstyle = {'innerstyle'},
abovestyle = {'abovestyle', 'стиль_вверху'},
belowstyle = {'belowstyle', 'стиль_внизу'},
imagestyle = {'imagestyle', 'стиль_изображения'},
imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}}
local standardAliases = {
groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'},
liststyle = {'liststyle', 'стиль_списков'},
evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'},
groupwidth = {'groupwidth', 'ширина_групп'},
listpadding = {'listpadding', 'отступ_списков'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией
local standardElementAliases = {
group = {'group%s', 'заголовок%s', 'группа%s'},
list = {'list%s', 'список%s'},
groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль_списка%s'},
listpadding = {'list%spadding'}
}
-- параметры {{навигационная таблица с блоками}}
-- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases
local groupsParentAliases = {
selected = {'selected', 'открытый_блок', 'развернуть'},
secttitlestyle = {'secttitlestyle', 'стиль_заголовков'},
_groupstyle = {'groupstyle', 'стиль_блоков'},
_liststyle = {'liststyle', 'стиль_списков', 'contentstyle'},
_listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'}
}
-- параметры {{навигационная таблица с блоками}} с нумерацией
local groupsChildAliases = {
groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'},
state = {'state%s'},
title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'},
list1 = {'list%s', 'список%s', 'content%s'},
image = {'image%s', 'изображение%s'},
imageleft = {'imageleft%s', 'изображение_слева%s'},
secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'},
groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'},
color = {'цвет%s'}
}
local function checkAliases(args, aliases, index)
for _, alias in ipairs(aliases) do
local arg
if index then
arg = args[string.format(alias, index)]
else
arg = args[alias]
end
if arg then
return arg
end
end
return nil
end
local function checkElAliases(args, name, index)
return checkAliases(args, standardElementAliases[name], index)
end
local function concatStyles(t)
local res
for k, v in pairs(t) do
if v then
res = res and res .. ';' .. v or v
end
end
return res
end
local function striped(wikitext, args)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]'
if args.border == 'subgroup' and args.orphan ~= 'yes' then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = 'odd', 'even'
if args.evenodd then
if args.evenodd == 'swap' then
first, second = second, first
else
first = args.evenodd
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count
end
local function addNewline(s)
if s:match('^[*:;#]') or s:match('^{|') then
return '\n' .. s ..'\n'
else
return s
end
end
local function renderNavBar(titleCell, args)
local currentFrame = mw.getCurrentFrame()
if args.navbar ~= 'off' and args.navbar ~= 'plain'
and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then
--- Gear creation
titleCell
:tag('span')
:addClass('navbox-gear')
:css('float', 'left')
:css('text-align', 'left')
:css('width', '5em')
:css('margin-right', '0.5em')
:wikitext(navbar{
args.name,
['fontstyle'] = args.titlestyle or args.basestyle
})
end
end
--
-- Title row
--
local function renderTitleRow(tbl, args)
if not args.title then return end
local titleRow = tbl:tag('tr')
if args.titlegroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
:cssText(args.groupstyle)
:cssText(args.titlegroupstyle)
:wikitext(args.titlegroup)
end
local titleCell = titleRow:tag('th'):attr('scope', 'colgroup')
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
:cssText(args.basestyle)
:cssText(args.titlestyle)
:addClass('navbox-title')
:attr('colspan', titleColspan)
renderNavBar(titleCell, args)
titleCell
:tag('div')
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 5em')
:wikitext(addNewline(args.title))
end
--
-- Above/Below rows
--
local function getAboveBelowColspan(args)
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl, args)
if not args.above then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.above))
end
local function renderBelowRow(tbl, args)
if not args.below then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.below))
end
--
-- List rows
--
local function haveSubgroups(args)
for i = 1, 23 do
if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then
return true
end
end
return false
end
local function renderListRow(tbl, args, index, rowspan, rowArgs)
local row = tbl:tag('tr')
if index == 1 and args.imageleft then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 7px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.imageleft))
end
if rowArgs.group then
local groupCell = row:tag('th')
groupCell
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.groupclass)
:cssText(args.basestyle)
:css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width
groupCell
:cssText(args.groupstyle)
:cssText(rowArgs.groupstyle)
:wikitext(rowArgs.group)
end
local listCell = row:tag('td')
if rowArgs.group then
listCell
:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
if haveSubgroups(args) then
listCell
:attr('colspan', 2)
end
end
if not args.groupwidth then
listCell:css('width', '100%')
end
local listText = rowArgs.list
local oddEven = ODD_EVEN_MARKER
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
end
listCell
:css('padding', '0px')
:cssText(args.liststyle)
:cssText(rowArgs.liststyle)
:addClass('navbox-list')
:addClass('navbox-' .. oddEven)
:addClass(args.listclass)
:addClass(rowArgs.listclass)
:tag('div')
:css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em')
:wikitext(addNewline(listText))
if index == 1 and args.image then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 0px 0px 7px')
:cssText(args.imagestyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.image))
end
end
--
-- Tracking categories
--
local function needsChangetoSubgroups(args)
for i = 1, 23 do
if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then
return true
end
end
return false
end
local function needsHorizontalLists(args)
if args.border == 'subgroup' or args.tracking == 'no' then
return false
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
-- local function hasBackgroundColors()
-- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background')
-- end
local function isIllegible(args)
if not styleratio then
styleratio = require('Module:Color contrast')._styleratio
end
for key, style in pairs(args) do
if tostring(key):match("style$") or tostring(key):match("^стиль") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(args)
local cats = {}
if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end
if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end
if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end
return cats
end
local function renderTrackingCategories(builder, args)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end
for i, cat in ipairs(getTrackingCategories(args)) do
builder:wikitext('[[Категория:' .. cat .. ']]')
end
end
--
-- Main navbox tables
--
local function renderMainTable(args, listnums)
local tbl = mw.html.create('table')
:addClass('nowraplinks')
:addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
:addClass('collapsible')
:addClass(args.state or 'autocollapse')
end
tbl:css('border-spacing', 0)
if args.border == 'subgroup' or args.border == 'none' then
tbl
:addClass('navbox-subgroup')
:cssText(args.bodystyle)
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args.innerstyle)
renderTitleRow(tbl, args)
renderAboveRow(tbl, args)
for i, listnum in ipairs(listnums) do
local rowArgs = {
group = checkElAliases(args, 'group', listnum),
list = checkElAliases(args, 'list', listnum),
groupstyle = checkElAliases(args, 'groupstyle', listnum),
listclass = checkElAliases(args, 'listclass', listnum),
liststyle = checkElAliases(args, 'liststyle', listnum),
listpadding = checkElAliases(args, 'listpadding', listnum)
}
renderListRow(tbl, args, i, #listnums, rowArgs)
end
renderBelowRow(tbl, args)
return tbl
end
-- Read the arguments in the order they'll be output in, to make references number in the right order.
local function readInTheRightOrder(args, groupAliases, listAliases)
local _
_ = checkAliases(args, commonAliases.title)
_ = checkAliases(args, commonAliases.above)
for i = 1, 23 do
_ = checkAliases(args, groupAliases, i)
_ = checkAliases(args, listAliases, i)
end
_ = checkAliases(args, commonAliases.below)
end
function p._navbox(args)
if not yesno then
yesno = require('Module:Yesno')
end
local listnums = {}
for k, v in pairs(args) do
local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
table.sort(listnums)
args.border = mw.text.trim(args.border or args[1] or '')
if args.border == 'child' then
args.border = 'subgroup'
end
for argname, aliasesList in pairs(commonAliases) do
args[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(standardAliases) do
args[argname] = checkAliases(args, aliasesList)
end
args.navigation = yesno(args.navigation, '')
-- render the main body of the navbox
local tbl = renderMainTable(args, listnums)
-- render the appropriate wrapper around the navbox, depending on the border param
local res = mw.html.create()
if args.border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
elseif args.border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
:node(tbl)
:wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:cssText(args.bodystyle)
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
end
renderTrackingCategories(res, args)
return striped(tostring(res), args)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
if not yesno then
yesno = require('Module:Yesno')
end
args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}})
if frame.args.border then
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
args.border = frame.args.border
end
readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list)
return p._navbox(args)
end
function p.navboxWithCollapsibleGroups(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}})
readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1)
local parent = {}
for argname, aliasesList in pairs(commonAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(groupsParentAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for i = 1, 20 do
local child = {}
for argname, aliasesList in pairs(groupsChildAliases) do
child[argname] = checkAliases(args, aliasesList, i)
end
child.color = child.color and string.format('background:%s;', child.color) or ''
child.border = 'child'
child.navbar = 'plain'
if parent.selected and parent.selected == child.groupname then
child.state = 'uncollapsed'
end
child.state = child.state or 'collapsed'
child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle}
child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color}
child.liststyle = concatStyles{parent._liststyle, child.liststyle}
child.lispadding = parent._listpadding
if child.title then
parent['list' .. i] = p._navbox(child)
else
parent['list' .. i] = child.list1
end
end
return p._navbox(parent)
end
return p
cf72974326d19e1d4d58d2d00766b944b3ca0944
Модуль:Color contrast
828
34
79
78
2025-01-31T15:24:07Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
--
-- This module implements
-- {{Color contrast ratio}}
-- {{Greater color contrast ratio}}
-- {{ColorToLum}}
-- {{RGBColorToLum}}
--
local p = {}
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )
local function sRGB ( v )
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function rgbdec2lum( R, G, B )
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
return ''
end
end
local function hsl2lum( h, s, l )
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
local c = (1 - math.abs(2*l - 1))*s
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
local m = l - c/2
local r, g, b = m, m, m
if( 0 <= h and h < 60 ) then
r = r + c
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
local function color2lum( c )
if (c == nil) then
return ''
end
-- whitespace
c = c:match( '^%s*(.-)[%s;]*$' )
-- lowercase
c = c:lower()
-- first try to look it up
local L = HTMLcolor[c]
if (L ~= nil) then
return L
end
-- convert from hsl
if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
end
-- convert from rgb
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
-- convert from rgb percent
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
end
-- remove leading # (if there is one) and whitespace
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
return rgbdec2lum(R, G, B)
end
-- failure, return blank
return ''
end
function p._greatercontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
local v1 = color2lum(args[1] or '')
local c2 = args[2] or '#FFFFFF'
local v2 = color2lum(c2)
local c3 = args[3] or '#000000'
local v3 = color2lum(c3)
local ratio1 = 0;
local ratio2 = 0;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end
return (ratio1 + bias > ratio2) and c2 or c3
end
function p._ratio(args)
local v1 = color2lum(mw.text.unstripNoWiki(args[1] or ''))
local v2 = color2lum(mw.text.unstripNoWiki(args[2] or ''))
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end
function p._styleratio(args)
local style = (args[1] or ''):lower()
local bg, fg = 'white', '#202122'
local lum_bg, lum_fg = 1, 0.016
if args[2] then
local lum = color2lum(args[2])
if lum ~= '' then bg, lum_bg = args[2], lum end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then fg, lum_fg = args[3], lum end
end
local slist = mw.text.split(style or '', ';')
for k = 1, #slist do
local s = slist[k]
local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
k = k or ''
v = v or ''
if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_bg = v, lum end
elseif (k:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_fg = v, lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
function p.lum(frame)
return color2lum(frame.args[1] or frame:getParent().args[1])
end
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
end
function p.styleratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._styleratio(args)
end
function p.greatercontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._greatercontrast(args)
end
return p
cce580326bee8eaf3c81df6c76c04a9a2909dfa2
Модуль:Color contrast/colors
828
35
81
80
2025-01-31T15:24:07Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
return {
aliceblue = 0.92880068253475,
antiquewhite = 0.84646951707754,
aqua = 0.7874,
aquamarine = 0.8078549208338,
azure = 0.97265264954166,
beige = 0.8988459998705,
bisque = 0.80732327372979,
black = 0,
blanchedalmond = 0.85084439608156,
blue = 0.0722,
blueviolet = 0.12622014321946,
brown = 0.098224287876511,
burlywood = 0.51559844533893,
cadetblue = 0.29424681085422,
chartreuse = 0.76032025902623,
chocolate = 0.23898526114557,
coral = 0.37017930872924,
cornflowerblue = 0.30318641994179,
cornsilk = 0.93562110372965,
crimson = 0.16042199953026,
cyan = 0.7874,
darkblue = 0.018640801980939,
darkcyan = 0.20329317839046,
darkgoldenrod = 0.27264703559993,
darkgray = 0.39675523072563,
darkgreen = 0.091143429047575,
darkgrey = 0.39675523072563,
darkkhaki = 0.45747326349994,
darkmagenta = 0.07353047651207,
darkolivegreen = 0.12651920884889,
darkorange = 0.40016167026524,
darkorchid = 0.13413142174857,
darkred = 0.054889674531132,
darksalmon = 0.40541471563381,
darkseagreen = 0.43789249325969,
darkslateblue = 0.065792846227988,
darkslategray = 0.067608151928044,
darkslategrey = 0.067608151928044,
darkturquoise = 0.4874606277449,
darkviolet = 0.10999048339343,
deeppink = 0.23866895828276,
deepskyblue = 0.44481603395575,
dimgray = 0.14126329114027,
dimgrey = 0.14126329114027,
dodgerblue = 0.27442536991456,
firebrick = 0.10724525535015,
floralwhite = 0.95922484825004,
forestgreen = 0.18920812076002,
fuchsia = 0.2848,
gainsboro = 0.71569350050648,
ghostwhite = 0.94311261886323,
gold = 0.69860877428159,
goldenrod = 0.41919977809569,
gray = 0.2158605001139,
green = 0.15438342968146,
greenyellow = 0.80609472611453,
grey = 0.2158605001139,
honeydew = 0.96336535554782,
hotpink = 0.34658438169715,
indianred = 0.21406134963884,
indigo = 0.03107561486337,
ivory = 0.99071270600615,
khaki = 0.77012343394121,
lavender = 0.80318750514521,
lavenderblush = 0.90172748631046,
lawngreen = 0.73905893124963,
lemonchiffon = 0.94038992245622,
lightblue = 0.63709141280807,
lightcoral = 0.35522120733135,
lightcyan = 0.94587293494829,
lightgoldenrodyellow = 0.93348351018297,
lightgray = 0.65140563741982,
lightgreen = 0.69091979956865,
lightgrey = 0.65140563741982,
lightpink = 0.58566152734898,
lightsalmon = 0.4780675225206,
lightseagreen = 0.35050145117042,
lightskyblue = 0.56195637618331,
lightslategray = 0.23830165007287,
lightslategrey = 0.23830165007287,
lightsteelblue = 0.53983888284666,
lightyellow = 0.98161818392882,
lime = 0.7152,
limegreen = 0.44571042246098,
linen = 0.88357340984379,
magenta = 0.2848,
maroon = 0.045891942324215,
mediumaquamarine = 0.49389703310801,
mediumblue = 0.044077780212328,
mediumorchid = 0.21639251153773,
mediumpurple = 0.22905858091648,
mediumseagreen = 0.34393112338131,
mediumslateblue = 0.20284629471622,
mediumspringgreen = 0.70704308194184,
mediumturquoise = 0.5133827926448,
mediumvioletred = 0.14371899849357,
midnightblue = 0.02071786635086,
mintcream = 0.97834604947588,
mistyrose = 0.82183047859185,
moccasin = 0.80083000991567,
navajowhite = 0.76519682342785,
navy = 0.015585128108224,
oldlace = 0.91900633405549,
olive = 0.20027537200568,
olivedrab = 0.22593150951929,
orange = 0.4817026703631,
orangered = 0.25516243753416,
orchid = 0.31348806761439,
palegoldenrod = 0.78792647887614,
palegreen = 0.77936759006353,
paleturquoise = 0.76436077921714,
palevioletred = 0.28754994117889,
papayawhip = 0.87797100199835,
peachpuff = 0.74905589878251,
peru = 0.30113074877936,
pink = 0.63271070702466,
plum = 0.45734221587969,
powderblue = 0.68254586500605,
purple = 0.061477070432439,
rebeccapurple = 0.07492341159447,
red = 0.2126,
rosybrown = 0.32319457649407,
royalblue = 0.16663210743188,
saddlebrown = 0.097922285020521,
salmon = 0.36977241527596,
sandybrown = 0.46628543696283,
seagreen = 0.19734199706275,
seashell = 0.92737862206922,
sienna = 0.13697631337098,
silver = 0.52711512570581,
skyblue = 0.55291668518184,
slateblue = 0.14784278062136,
slategray = 0.20896704076536,
slategrey = 0.20896704076536,
snow = 0.96533341834849,
springgreen = 0.73052306068529,
steelblue = 0.20562642207625,
tan = 0.48237604163921,
teal = 0.16996855778968,
thistle = 0.56818401093733,
tomato = 0.30638612719415,
turquoise = 0.5895536427578,
violet = 0.40315452986676,
wheat = 0.74909702820482,
white = 1,
whitesmoke = 0.91309865179342,
yellow = 0.9278,
yellowgreen = 0.50762957208707,
}
6ae47fdb24de4eed5ec26d203faf5341a388987b
Шаблон:Yesno-yes
10
36
83
82
2025-01-31T15:24:07Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>
{{doc}}
</noinclude>
3792ff694708f98102e3a6d556abe73bedc29069
Шаблон:Навигационная таблица
10
37
85
84
2025-01-31T15:24:09Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон
| {{#switch: {{{1|{{{border|}}}}}}
| child | subgroup | none =
| {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}}
|
| {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}}
|
| {{#if: {{{имя|{{{name|}}}}}}
| {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}}
| [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]]
}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c
Шаблон:No-doc
10
38
87
86
2025-01-31T15:24:09Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#ifeq: {{SUBPAGENAME}} | doc
|| {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }}
|| {{{1|}}}
}}
}}<noinclude>{{doc}}</noinclude>
da013ca5b5f97f94bee392ff3a4488046f2ceac7
Модуль:Separated entries
828
39
89
88
2025-01-31T15:24:10Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux".
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.newline = makeInvokeFunction('\n')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
33a68f0a46d62c42b6523a548f0f881e82ecfe58
Шаблон:T
10
40
91
90
2025-01-31T15:24:10Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tl]]
c0a76efe437d8a513d9f6878297f399a23944abd
Шаблон:Tl
10
41
93
92
2025-01-31T15:24:11Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude>
61fe4d068895a5e7e5802767f5d7df71a7561c57
Шаблон:Str sub
10
42
95
94
2025-01-31T15:24:11Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude>
{{doc}}
</noinclude>
3043790f8803e868cf6097b475fd58ba742887fe
Шаблон:Начало скрытого блока
10
43
97
96
2025-01-31T15:24:11Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!--
--><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!--
--><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!--
-->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!--
-->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!--
--><div class="mw-collapsible-toggle-placeholder"></div></div><!--
--><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!--
-->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!--
--></includeonly><noinclude>
{{doc}}
</noinclude>
3b96bb802b522e629c41cddc5d44dfb2a9eb462a
Шаблон:Скрытый блок/styles.css
10
44
99
98
2025-01-31T15:24:11Z
Генерал Альдации
2
1 версия импортирована
text
text/plain
.ts-Скрытый_блок {
margin: 0;
overflow: hidden;
border-collapse: collapse;
box-sizing: border-box;
}
.ts-Скрытый_блок-title {
text-align: center;
font-weight: bold;
line-height: 1.6em;
min-height: 1.2em;
}
.ts-Скрытый_блок .mw-collapsible-content {
overflow-x: auto;
overflow-y: hidden;
clear: both;
}
.ts-Скрытый_блок::before,
.ts-Скрытый_блок .mw-collapsible-toggle {
padding-top: .1em;
width: 6em;
font-weight: normal;
font-size: calc(90% / 0.95);
}
.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
float: right;
text-align: right;
}
.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
float: left;
text-align: left;
}
.ts-Скрытый_блок-gray {
padding: 2px;
border: 1px solid var(--border-color-base, #a2a9b1);
}
.ts-Скрытый_блок-transparent {
border: none;
}
.ts-Скрытый_блок-gray .ts-Скрытый_блок-title {
background: var(--background-color-neutral, #eaecf0);
padding: .1em 6em;
padding-right: 0;
}
.ts-Скрытый_блок-transparent .ts-Скрытый_блок-title {
background: transparent;
padding: .1em 5.5em;
padding-right: 0;
}
.ts-Скрытый_блок-gray .mw-collapsible-content {
padding: .25em 1em;
}
.ts-Скрытый_блок-transparent .mw-collapsible-content {
padding: .25em 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 1em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 6.5em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 0;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-right: 0;
}
.ts-Скрытый_блок + .ts-Скрытый_блок,
.ts-Скрытый_блок + link + .ts-Скрытый_блок {
border-top-style: hidden;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b04b4e8d09f2a95b9b1ca08e8c10ef52169ec7f1
Шаблон:Ifempty
10
45
101
100
2025-01-31T15:24:11Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude>
{{Doc}}
<!-- Add categories and interwikis to the /doc subpage, not here!
Добавляйте категории и интервики на подстраницу документации, а не сюда -->
</noinclude>
c14bef2160201468f96da309e565ff2fde725cf5
Шаблон:Конец скрытого блока
10
46
103
102
2025-01-31T15:24:12Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly></div></div></includeonly><noinclude>
{{doc|Шаблон:Начало скрытого блока/doc}}</noinclude>
2da6ac8eb0812fb4183a70b516009d40920e281f
Шаблон:Str len
10
47
105
104
2025-01-31T15:24:12Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
95f10258d5214440d2706952656564f216c2e4cc
Модуль:Ifempty
828
48
107
106
2025-01-31T15:24:12Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
local getArgs = require('Module:Arguments').getArgs
function p.main(frame)
local args = getArgs(frame, {removeBlanks = false})
local before = args['до']
local after = args['после']
for i, v in ipairs(args) do
if v ~= '' then
return (before or '') .. v .. (after or '')
end
end
end
return p
875e8c9f03fb4cc02d80271ad3aaab13a9bcea86
Шаблон:Str rightc
10
49
109
108
2025-01-31T15:24:13Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude>
0401d500dcc2224d44867ba0ea1f6c0fbeb758a0
Модуль:Hash
828
50
111
110
2025-01-31T15:24:13Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function inTable(table, value)
for k, v in pairs(table) do
if v == value then
return true
end
end
return false
end
function p.list(frame)
return table.concat(mw.hash.listAlgorithms(), '; ')
end
function p.main(frame)
local args = getArgs(frame, { frameOnly = true })
local algorithm
if not args[1] then
return '<span class="error">Не указана строка для хеширования.</span>'
end
if args[2] then
if not inTable(mw.hash.listAlgorithms(), args[2]) then
return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>'
end
algorithm = args[2]
else
-- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]),
-- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой
-- величины. Возможно, есть лучшая опция — проверяйте.
algorithm = 'fnv164'
end
return mw.hash.hashValue(algorithm, args[1])
end
return p
5d18513e574435f191164695449a620b031f93ec
Шаблон:Скрытый блок
10
51
113
112
2025-01-31T15:24:13Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{Начало скрытого блока
|id = {{{id|}}}
|тип = {{{тип|{{{type|}}}}}}
|состояние = {{{state|{{{состояние|collapsed}}}}}}
|класс_тела = {{{класс_тела|{{{класс тела|}}}}}}
|стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}
|рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}}
|заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}
|ссылка = {{{Ссылка|{{{ссылка|}}}}}}
|класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}}
|шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}}
|наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}}
|фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}}
|выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}
|стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}}
|класс_текста = {{{класс_текста|{{{класс текста|}}}}}}
|шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}}
|наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}}
|фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}}
|выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}}
|стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}}
{{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}}
{{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }}
{{Конец скрытого блока}}<noinclude>
{{doc}}
</noinclude>
792dc9fb2eb659877e2e758f4ce405e1d3f8352b
Шаблон:Tlp
10
52
115
114
2025-01-31T15:24:13Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude>
36c309cb28ccf0901f4fff46cbd35cdabcf00661
Шаблон:Doc
10
53
117
116
2025-01-31T15:24:14Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}}
{{#if: {{{1|}}}
| {{#ifexist: {{#if: {{NAMESPACE:{{{1}}}}} | {{{1}}} | {{SUBJECTSPACE}}:{{{1}}} }}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{#ifexist: {{SUBJECTSPACE}}:{{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{Документировать|{{{1}}}}}
}}
}}
| {{#ifexist: {{SUBJECTPAGENAME}}/doc
| {{{{SUBJECTPAGENAME}}/doc}}
| {{Документировать|{{SUBJECTPAGENAME}}/doc}}
}}
}}
{{doc/end}}</includeonly><noinclude>
{{doc}}
</noinclude>
7298506ab2882f16fe7a52e0e080b2780b237bb9
Шаблон:Doc/begin
10
54
119
118
2025-01-31T15:24:14Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Doc/styles.css" />
<div class="ts-doc-doc" id="doc">
<div class="ts-doc-header" id="Документация">
<div class="ts-doc-heading">Документация</div>
{{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }}
</div>
<div class="ts-doc-content"></includeonly><noinclude>
{{doc}}
</noinclude>
c753f0a9f65d86707cdffaf93fb49c2c52daf92b
Шаблон:Doc/styles.css
10
55
121
120
2025-01-31T15:24:14Z
Генерал Альдации
2
1 версия импортирована
text
text/plain
.ts-doc-doc {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
clear: both;
margin-top: 1em;
}
/* Ctrl+F ":target" in [[MediaWiki:Common.css]] */
.ts-doc-doc sup.reference:target,
.ts-doc-doc ol.references li:target,
.ts-doc-doc .highlight-target:target,
.ts-doc-doc cite:target,
.ts-doc-doc span.citation:target {
background: var(--ruwiki-background-color-blue200, #cfe3ff);
}
.ts-doc-header {
align-items: center;
background: var(--ruwiki-background-color-blue200, #cfe3ff);
display: flex;
flex-wrap: wrap;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
margin-left: auto;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 2em;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat;
background-size: contain;
font-size: small;
min-height: 1.75em;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media screen {
html.skin-theme-clientpref-night .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header {
display: block;
}
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
be8d912472a37a6051bee114da86f913839e7ca0
Шаблон:Действия для страницы
10
56
123
122
2025-01-31T15:24:14Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!--
-->{{join|separator=<span class="mw-editsection-divider"> &#124; </span>
|1={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }}
}}
|2={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]]
}}
|3={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }}
}}
|4={{#ifexist: {{#rel2abs: {{{lc|}}} }}
|
| [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать]
}}
|5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }}
|6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }}
}}<span class="mw-editsection-bracket">]</span></div><noinclude>
{{doc}}
</noinclude>
9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4
Шаблон:Действия для страницы/styles.css
10
57
125
124
2025-01-31T15:24:15Z
Генерал Альдации
2
1 версия импортирована
text
text/plain
.ts-tlinks-tlinks {
font-weight: normal;
float: right;
line-height: inherit;
}
.ts-tlinks-tlinks .mw-editsection-divider {
display: inline;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
a003e896d263c29e66d2246b210e5d73e577ea46
Шаблон:Doc/end
10
58
127
126
2025-01-31T15:24:15Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Модуль:Песочница|песочнице для модулей]]
| своём [[ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}</noinclude>
758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e
Шаблон:Ombox
10
59
129
128
2025-01-31T15:24:15Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
ab34435c5ebc29de589c9b059e88da5d0e6f16e4
Шаблон:Docpage
10
60
131
130
2025-01-31T15:24:16Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#ifeq: {{SUBPAGENAME}} | doc
| {{fmbox
| class = hlist nowraplinks
| style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff);
| image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]]
| text = <div>
* [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]]
* [[:{{SUBJECTPAGENAME}}|Документация]]
* [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]]
* [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} |
** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}}
}}</div><!--
-->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }}
}}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Категория:Модули:Документация]]
| [[Категория:Шаблоны:Документация]]
}}__EXPECTED_UNCONNECTED_PAGE__
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
e2d07566c50be35ac409e8396893a3b9d8676e0c
Шаблон:Очистить кэш
10
61
133
132
2025-01-31T15:24:16Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}}
| {{ns:10}} <!-- Шаблон -->
| {{очищать кэш|ежедневно}}
}}<noinclude>{{doc}}</noinclude>
be6695060ca61d2125386d02d3a19109c0e7c27b
Шаблон:Скрытый
10
62
135
134
2025-01-31T15:24:16Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Скрытый блок]]
97cc939c1c8ece875b2ec360f85980bd6f1bbed7
Модуль:Navbar
828
63
137
136
2025-01-31T15:24:17Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
local hlist = 'Template:Flatlist/styles.css'
local templatestyles = 'Module:Navbar/styles.css'
local getArgs
function p._ruwikiNavbar( args )
local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local whiteColorDefs = {
['#fff'] = true,
['#ffffff'] = true,
['white'] = true,
}
local fontColor = args.fontcolor and args.fontcolor:lower()
local isWhite = fontColor and whiteColorDefs[ fontColor ] == true
local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() )
if not isWhite and fontStyle then
local styleratio = require( 'Module:Color contrast' )._styleratio
isWhite = styleratio( {
fontStyle .. '; color:#666;',
'',
'#666'
} ) < 3.66
end
local isTemplate = title.namespace == 10
local altText = string.format(
'Перейти %s «%s»',
isTemplate and 'к шаблону' or 'на страницу',
mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ]
)
return string.format(
'[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]',
isWhite and ' white' or '',
isWhite and '' or ' skin-invert-image',
tostring( title ),
altText
)
end
function p.ruwikiNavbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._ruwikiNavbar(getArgs(frame))
end
function p._navbar(args)
local titleArg = 1
if args.collapsible then
titleArg = 2
if not args.plain then
args.mini = 1
end
if args.fontcolor then
args.fontstyle = 'color:' .. args.fontcolor .. ';'
end
args.style = 'float:left; text-align:left; white-space:nowrap;'
end
if args[titleArg] == 'off' then
return
end
local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or '';
local tag
if args.nodiv then
tag = 'span'
else
tag = 'div'
end
local div = mw.html.create():tag(tag)
div
:addClass('navbar hlist plainlinks noprint')
:attr('data-navboxnavigation-link', '0')
:cssText(args.style)
if args.mini then div:addClass('navbar-mini') end
if not (args.mini or args.plain) then
div
:tag('span')
:addClass('navbar-boxtext')
:cssText(args.fontstyle)
:wikitext(args.text or 'Шаблон:')
:wikitext(' ')
end
local ul = div:tag('ul');
if args.brackets then
ul:addClass('navbar-brackets')
end
ul
:tag('li')
:addClass('nv-view')
:wikitext('[[' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:addClass(args.mini and 'navbar-mini-abbr')
:attr('title', 'Просмотр этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'п' or 'просмотр')
:done()
:wikitext(']]')
:done()
:tag('li')
:addClass('nv-talk')
:wikitext('[[' .. talkpage .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Обсуждение этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'о' or 'обсуждение')
:done()
:wikitext(']]');
if not args.noedit then
ul
:tag('li')
:addClass('nv-edit')
:wikitext('[[Special:EditPage/' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Править этот шаблон')
:cssText(args.fontstyle)
:wikitext(args.mini and 'р' or 'править')
:done()
:wikitext(']]');
end
if args.collapsible then
div:done()
:tag('span')
:addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' )
:cssText(args.fontstyle)
:wikitext(args[1])
end
local frame = mw.getCurrentFrame()
return frame:extensionTag{
name = 'templatestyles', args = { src = hlist }
} .. frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
} .. tostring(div:done())
end
function p.navbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._navbar(getArgs(frame))
end
return p
695777e4dafbd5f7bf8b4f35d8db9349d08a363d
Шаблон:OnLua
10
64
139
138
2025-01-31T15:24:17Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua]]
b72371e7ae22239863c474a78238171c2bd94c7e
Шаблон:Tnav
10
65
141
140
2025-01-31T15:24:17Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude>
{{doc-inline}}
Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}.
{{шаблоны для документирования}}
{{doc-end}}
[[Категория:Шаблоны:Ссылки на шаблоны]]
[[Категория:Шаблоны:Для навигационных шаблонов]]
</noinclude>
583d607aa213790ae32dda4018a413255493e42b
Шаблон:Выполнить скрипт
10
66
143
142
2025-01-31T15:24:17Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{{1|}}}
| =
| mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]]
| #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }}
}}<noinclude>
{{doc}}
</noinclude>
6979ea0342067dc76b9adcb9a5e072207c2c5a63
Шаблон:OnLua/Строка
10
67
145
144
2025-01-31T15:24:18Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua/Строка]]
d7f869ccc7a7efc800399fce32bc75e0f91066de
Шаблон:Дерево категорий
10
68
147
146
2025-01-31T15:24:18Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<div>{{{title|'''Дерево категорий'''}}}
{{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}}
| mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}}
| depth = {{#if:{{{3}}}|{{{3}}}}}
}}
</div><noinclude>
{{doc}}
</noinclude>
9763d532ff7b79a638abe485875db984254b57db
Шаблон:СИШ
10
69
149
148
2025-01-31T15:24:18Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<noinclude>{{к объединению|2020-11-10|Шаблон:High-use}}
</noinclude>{{ombox
|type = notice
|image = [[Файл:Stalewarning.svg|40px|alt=Время]]
|text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].'''
|text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений].
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude>
{{doc}}
</noinclude>
013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b
Шаблон:Подстраницы шаблона Карточка
10
70
151
150
2025-01-31T15:24:19Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{Навигационная таблица
|имя = Подстраницы шаблона Карточка
|state = {{{state|}}}
|класс_списков = hlist hlist-items-nowrap
|заголовок = Подстраницы шаблона {{tnav|Карточка}}
|tracking = <includeonly>no</includeonly>
|группа1 = {{!}}вверху=
|список1 =
* {{tnav|карточка/название}} (заголовок без уточнения)
* {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения)
|группа2 = {{!}}вверху2=
|список2 =
* {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]])
* {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]])
* {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]])
* {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]])
|группа3 = Разное
|список3 =
* {{tnav|карточка/изображение}}
* {{tnav|карточка/Изображение рядом}}
* {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]])
* {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]])
* {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]])
* {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]])
* {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]])
* {{tnav|карточка/блок}}
* {{tnav|карточка/блок с маркерами}}
|группа4 = {{!}}внизу=
|список4 =
* {{tnav|карточка/Викигид}}
* {{tnav|карточка/Викиданные}}
* {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]])
* {{tnav|карточка/Викитека}}
* {{tnav|карточка/Викиучебник}}
* {{tnav|карточка/Викицитатник}}
|класс_внизу = hlist
|внизу =
; См. также
: [[Википедия:Шаблоны-карточки]]
: [[:Категория:Шаблоны:Для шаблонов-карточек]]
}}<noinclude>
[[Категория:Навигационные шаблоны:Для шаблонов]]
</noinclude>
3fd4b54a761d9de6d7ddaac86889f4abf8478d95
Шаблон:Lua
10
71
153
152
2025-01-31T15:24:19Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{ombox
| small = yes
| style = width:23em;
| image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]]
| text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|:<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}| с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из }}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!--
-->{{#invoke:Transclude|npc|OnLua/Строка|
module=
|function=
|tech=
|line=
}}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}}
}}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude>
f1fdaa87edb15d61e23e98f6e25d171a975e10eb
Шаблон:Карточка/doc
10
72
155
154
2025-01-31T15:24:20Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}}
{{СИШ}}
Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]].
== Параметры ==
=== Служебные ===
; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>.
; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да».
; from: Указывается элемент Викиданных, из которого берётся информация.
=== Основные ===
; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи.
; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия.
; вверху3: Дополнительный текст, отображаемый вверху таблицы.
; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>.
; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется.
; изображение2: Дополнительное изображение.
; изображение3: Дополнительное изображение.
; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1.
; метка<sub>n</sub>: Используется для подписи текста
; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках.
; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в <tr>, таких как {{t|карточка/блок}}.
; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. Для вариантов форматирования значений, см. документацию [[Модуль:WikidataSelectors]].
; внизу
; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом).
=== Стили ===
; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}}
; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code>
; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code>
; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code>
; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание
; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение
; стиль_подписи: Применяется к подписи изображения
; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code>
; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n
; стиль_меток: Применяется к меткам
; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n
; стиль_текста: Применяется к тексту
; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n
; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''.
; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам.
== Возможности ==
=== Сдвоенные ячейки ===
Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код:
<pre><nowiki>
|текст2 = {{{параметр|}}}
|стиль_текста2 = text-align:left;
</nowiki></pre>
=== Необязательные ячейки ===
Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом:
<pre><nowiki>
|метка5 = Население
|текст5 = {{{население|}}}
</nowiki></pre>
Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена.
=== Необязательные заголовки ===
Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>:
<pre><nowiki>
|заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}}
|метка6 = Содержимое
|текст6 = {{{содержимое|}}}
|метка7 = Размещение
|текст7 = {{{размещение|}}}
</nowiki></pre>
Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN.
{|
|-
|<pre><nowiki>
|заголовок1 = {{{заголовок1|}}}
|метка1 = {{{метка1|}}}
|текст1 = {{{текст1|}}}
</nowiki></pre>
|}
{|
|-
|<pre><nowiki>
|заголовок1 = заголовок_текст
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
! заголовок_текст
|}
|<pre><nowiki>
|заголовок1 =
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
| метка_текст|| текст_текст
|}
|}
=== Оформление параметров ===
Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён:
<pre><nowiki>
|метка6 = Масса
|текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}}
</nowiki></pre>
А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например:
<pre><nowiki>
|метка6 = Раса
|текст6 = {{#switch:{{{раса|}}}
|Европеоиды = [[Европеоидная раса|Европеоиды]]
|Негроиды = [[Негроидная раса|Негроиды]]
|Монголоиды = [[Монголоидная раса|Монголоиды]]
|{{{раса|}}}
}}
</nowiki></pre>
== Пустой шаблон ==
<pre>
{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху =
|вверху2 =
|изображение =
|заголовок1 =
|метка2 =
|текст2 =
|викиданные2 =
|метка3 =
|текст3 =
|викиданные3 =
|метка4 =
|текст4 =
|викиданные4 =
|метка5 =
|текст5 =
|викиданные5 =
|метка6 =
|текст6 =
|викиданные6 =
|метка7 =
|текст7 =
|викиданные7 =
|метка8 =
|текст8 =
|викиданные8 =
|метка9 =
|текст9 =
|викиданные9 =
|метка10 =
|текст10 =
|викиданные10 =
...
|меткаN =
|текстN =
|викиданныеN =
|внизу =
}}<noinclude>
{{doc}}
</noinclude></pre>
{{скрытый|Заголовок=11—20|Содержание=<pre>
|метка11 =
|текст11 =
|викиданные11 =
|метка12 =
|текст12 =
|викиданные12 =
|метка13 =
|текст13 =
|викиданные13 =
|метка14 =
|текст14 =
|викиданные14 =
|метка15 =
|текст15 =
|викиданные15 =
|метка16 =
|текст16 =
|викиданные16 =
|метка17 =
|текст17 =
|викиданные17 =
|метка18 =
|текст18 =
|викиданные18 =
|метка19 =
|текст19 =
|викиданные19 =
|метка20 =
|текст20 =
|викиданные20 =
</pre>}}
{{скрытый||Заголовок=21—30|Содержание=<pre>
|метка21 =
|текст21 =
|викиданные21 =
|метка22 =
|текст22 =
|викиданные22 =
|метка23 =
|текст23 =
|викиданные23 =
|метка24 =
|текст24 =
|викиданные24 =
|метка25 =
|текст25 =
|викиданные25 =
|метка26 =
|текст26 =
|викиданные26 =
|метка27 =
|текст27 =
|викиданные27 =
|метка28 =
|текст28 =
|викиданные28 =
|метка29 =
|текст29 =
|викиданные29 =
|метка30 =
|текст30 =
|викиданные30 =
</pre>}}
{{скрытый||Заголовок=31—40|Содержание=<pre>
|метка31 =
|текст31 =
|викиданные31 =
|метка32 =
|текст32 =
|викиданные32 =
|метка33 =
|текст33 =
|викиданные33 =
|метка34 =
|текст34 =
|викиданные34 =
|метка35 =
|текст35 =
|викиданные35 =
|метка36 =
|текст36 =
|викиданные36 =
|метка37 =
|текст37 =
|викиданные37 =
|метка38 =
|текст38 =
|викиданные38 =
|метка39 =
|текст39 =
|викиданные39 =
|метка40 =
|текст40 =
|викиданные40 =
</pre>}}
{{скрытый||Заголовок=41—50|Содержание=<pre>
|метка41 =
|текст41 =
|викиданные41 =
|метка42 =
|текст42 =
|викиданные42 =
|метка43 =
|текст43 =
|викиданные43 =
|метка44 =
|текст44 =
|викиданные44 =
|метка45 =
|текст45 =
|викиданные45 =
|метка46 =
|текст46 =
|викиданные46 =
|метка47 =
|текст47 =
|викиданные47 =
|метка48 =
|текст48 =
|викиданные48 =
|метка49 =
|текст49 =
|викиданные49 =
|метка50 =
|текст50 =
|викиданные50 =
</pre>}}
{{скрытый||Заголовок=51—60|Содержание=<pre>
|метка51 =
|текст51 =
|викиданные51 =
|метка52 =
|текст52 =
|викиданные52 =
|метка53 =
|текст53 =
|викиданные53 =
|метка54 =
|текст54 =
|викиданные54 =
|метка55 =
|текст55 =
|викиданные55 =
|метка56 =
|текст56 =
|викиданные56 =
|метка57 =
|текст57 =
|викиданные57 =
|метка58 =
|текст58 =
|викиданные58 =
|метка59 =
|текст59 =
|викиданные59 =
|метка60 =
|текст60 =
|викиданные60 =
</pre>}}
== Примерный шаблон для карточки персоны ==
<pre>{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху = {{карточка/имя|{{{имя|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}}
|изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|}}}
|викиданные1 = p1477
|метка2 = Дата рождения
|текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}}
|метка3 = Место рождения
|текст3 = {{{место рождения|}}}
|викиданные3 = p19
|метка4 = Дата смерти
|текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}}
|метка5 = Место смерти
|текст5 = {{{место смерти|}}}
|викиданные5 = p20
|метка6 = Гражданство
|текст6 = {{{гражданство|}}}
|викиданные6 = p27
|метка7 = Сценические имена / Прозвище
|текст7 = {{{прозвище|}}}
|викиданные7 = p1449
|заголовок8 = {{wikidata|p856|{{{сайт|}}}}}
|внизу = {{карточка/Викисклад|{{{викисклад|}}}}}
}}</pre>
Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом:
* <code>13.05.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* <code>12.06.1801 (31.05)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* <code>12.01.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
== Отслеживающие категории, подставляемые шаблоном ==
{{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}}
== См. также ==
* [[Википедия:Шаблоны-карточки]]
* {{t|Универсальная карточка}}
* {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке)
* [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]]
* [[Участник:Jack who built the house/alignTemplateParameters.js]]
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны-карточки|*]]
[[Категория:Шаблоны:Мета-шаблоны]]
</includeonly>
29badbe2200149ba091573e4e4e11106d20e0688
Модуль:Message box/ombox.css
828
73
157
156
2025-01-31T15:24:20Z
Генерал Альдации
2
1 версия импортирована
text
text/plain
/* Скопировано из [[:en:Module:Message box/ombox.css]] */
.ombox {
margin: 4px 0;
border-collapse: collapse;
border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */
background-color: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
}
/* For the "small=yes" option. */
.ombox.mbox-small {
font-size: 88%;
line-height: 1.25em;
}
.ombox-speedy {
border: 2px solid var(--border-color-error, #b32424); /* Red */
background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */
}
.ombox-delete {
border: 2px solid var(--background-color-error--active, #b32424); /* Red */
}
.ombox-content {
border: 1px solid #f28500; /* Orange */
}
.ombox-style {
border: 1px solid #fc3; /* Yellow */
}
.ombox-move {
border: 1px solid #9932cc; /* Purple */
}
.ombox-protection {
border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */
}
.ombox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.ombox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.ombox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ombox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
.ombox .mbox-invalid-type {
text-align: center;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.ombox .mbox-textsmall-div {
font-size: 90%;
}
@media (min-width: 720px) {
.ombox {
margin: 4px 10%;
}
.ombox.mbox-small {
/* @noflip */
clear: right;
/* @noflip */
float: right;
/* @noflip */
margin: 4px 0 4px 1em;
width: 238px;
}
/* Стили нотификаций для ноутбуков */
@media (max-width: 1366px) {
.ombox {
margin-left: 6%;
margin-right: 6%;
}
}
}
/* [[Категория:Модули:Подстраницы CSS]] */
6627874170f6674674bfa5796b2f7dfb6698cd81
Шаблон:Lua/Строка
10
74
159
158
2025-01-31T15:24:21Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из }}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude>
5a35837338c2daee2d240a8e5335e8fec8e7d87e
Шаблон:Langi
10
75
161
160
2025-01-31T15:24:21Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude>
7bb9f9098c88e770b982402adf30a3bbf645aa4b
Шаблон:Карточка/название
10
76
163
162
2025-01-31T15:24:21Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude>
{{doc}}
</noinclude>
110edc6d8286f120a048863c68371720bd4e65ca
Шаблон:Без уточнения
10
77
165
164
2025-01-31T15:24:21Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude>
1fcb3edb0be49656ae0f913e9a8fb4853264b480
Шаблон:Wikidata
10
78
167
166
2025-01-31T15:24:22Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude>
9d3d422eca39504b018df6ec0bb047392a7aba7e
Шаблон:Wikidata number switch
10
79
169
168
2025-01-31T15:24:22Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#if: {{{3|}}}
| {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }}
| {{#if: {{{2|}}}
| {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }}
| {{#if: {{{1|}}}
| {{#if: {{{4|}}}{{{5|}}}
| {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }}
| {{wikidata|{{{1|}}}|from={{{from|}}}}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
7541bb47e73905a8ee240baa1dab1801f9f7b166
Шаблон:Карточка/Викисклад
10
80
171
170
2025-01-31T15:24:22Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!--
-->{{#if: {{wikidata|p373|plain=true}}
| {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }}
| [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]]
}} }}<!--
--> }}<!--
-->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!--
--><noinclude>
{{doc}}
</noinclude>
40ef9a463c772ddbf54feae9e21d4037b692253e
Шаблон:Str rep
10
81
173
172
2025-01-31T15:24:23Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude>
c75032f150c372324c69a6f62ff4ab1492ad4cfa
Модуль:Wikidata
828
82
175
174
2025-01-31T15:24:23Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
---settings, may differ from project to project
local fileDefaultSize = '267x400px'
local outputReferences = true
local writingSystemElementId = 'Q8209'
local langElementId = 'Q7737'
---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании)
local moduleSources = require( 'Module:Sources' )
local WDS = require( 'Module:WikidataSelectors' )
---Константы
---@type string
local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode()
local p = {}
local g_config, g_frame
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement,
formatStatementDefault, getSourcingCircumstances, getPropertyParams
---@param obj table
---@param target table
---@param skipEmpty boolean | nil
---@return table
local function copyTo( obj, target, skipEmpty )
for key, val in pairs( obj ) do
if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then
target[ key ] = val
end
end
return target
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function min( prev, next )
if prev == nil or prev > next then
return next
end
return prev
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function max( prev, next )
if prev == nil or prev < next then
return next
end
return prev
end
---@param section string
---@param code string
---@return any | nil
local function getConfig( section, code )
if g_config == nil then
g_config = require( 'Module:Wikidata/config' )
end
if not g_config then
g_config = {}
end
if not section then
return g_config
end
if not code then
return g_config[ section ] or {}
end
if not g_config[ section ] then
return nil
end
return g_config[ section ][ code ]
end
---@param code string
---@param sortKey string | nil
---@return string
local function getCategoryByCode( code, sortKey )
local value = getConfig( 'categories', code )
if not value or value == '' then
return ''
end
if sortKey ~= nil then
return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать?
else
return '[[Category:' .. value .. ']]'
end
end
---@param isoStr string | table
---@return table | nil
local function splitISO8601( isoStr )
if 'table' == type( isoStr ) then
if isoStr.args and isoStr.args[ 1 ] then
isoStr = '' .. isoStr.args[ 1 ]
else
return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr )
end
end
local Y, M, D = ( function( str )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local _Y, _M, _D = mw.ustring.match( str, pattern )
return tonumber( _Y ), tonumber( _M ), tonumber( _D )
end )( isoStr )
local h, m, s = ( function( str )
local pattern = "T(%d+):(%d+):(%d+)%Z"
local _H, _M, _S = mw.ustring.match( str, pattern )
return tonumber( _H ), tonumber( _M ), tonumber( _S )
end )( isoStr )
local oh, om = ( function( str )
if str:sub(-1) == "Z" then -- ends with Z, Zulu time
return 0, 0
end
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern )
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber( sign .. oh ), tonumber( sign .. om )
end )( isoStr )
return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s }
end
---Внутренняя функции для получения границ временного диапазона
---@param time string
---@param precision number
---@return table | nil
function p._parseTimeBoundaries( time, precision )
local s = splitISO8601( time )
if not s then
return nil
end
if precision >= 0 and precision <= 8 then
local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }
local power = powers[ precision + 1 ]
local left = s.year - ( s.year % power )
return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 9 then
return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 }
end
if precision == 10 then
local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local lastDay = lastDays[ s.month ]
return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 11 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 12 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 13 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 14 then
local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) )
return { t * 1000, t * 1000 + 999 }
end
error( 'Unsupported precision: ' .. precision )
end
---Внутренняя функция для получения числового значения времени из snak'а
---@param table snak
---@return number | nil
function p._parseTimeFromSnak( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then
local timeData = splitISO8601( tostring( snak.datavalue.value.time ) )
timeData.month = math.max( timeData.month, 1 )
timeData.day = math.max( timeData.day, 1 )
return tonumber( os.time( timeData ) ) * 1000
end
return nil
end
---Функция для формирования категории на основе wikidata/config
---@param options table
---@param entityId string
---@return string
local function extractCategory( options, entityId )
if not entityId or not options.category or options.nocat then
return ''
end
if type( entityId ) ~= 'string' then
entityId = entityId.id
end
local claims = WDS.load( entityId, options.category )
if not claims then
return ''
end
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'wikibase-entityid'
then
local catEntityId = claim.mainsnak.datavalue.value.id
local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId )
if wbStatus and catSiteLink then
return '[[' .. catSiteLink .. ']]'
end
end
end
return ''
end
---Преобразует строку в булевое значение
---@param valueToParse string
---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях
local function toBoolean( valueToParse, defaultValue )
if valueToParse ~= nil then
if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then
return false
end
return true
end
return defaultValue
end
---Обрачивает отформатированное значение в инлайновый или блочный тег.
---@param value string value
---@param attributes table of attributes
---@return string HTML tag with value
local function wrapValue( value, attributes )
local tagName = 'span'
local spacer = ''
if string.match( value, '\n' )
or string.match( value, '<t[dhr][ >]' )
or string.match( value, '<div[ >]' )
or string.find( value, 'UNIQ%-%-imagemap' )
then
tagName = 'div'
spacer = '\n'
end
local attrString = ''
for key, val in pairs( attributes or {} ) do
local _key = mw.text.trim( key )
local _value = mw.text.encode( mw.text.trim( val ) )
attrString = attrString .. _key .. '="' .. _value .. '" '
end
return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>'
end
---Wraps formatted snak value into HTML tag with attributes.
---@param value string value of snak
---@param hash string
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapSnak( value, hash, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak'
if hash then
newAttributes[ 'data-wikidata-hash'] = hash
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted statement value into HTML tag with attributes.
---@param value string value of statement
---@param propertyId string PID of property
---@param claimId string ID of claim or nil for local value
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapStatement( value, propertyId, claimId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = newAttributes[ 'class' ] or ''
newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId )
if claimId then
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim'
newAttributes[ 'data-wikidata-claim-id' ] = claimId
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted qualifier's statement value into HTML tag with attributes.
---@param value string value of qualifier's statement
---@param qualifierId string PID of qualifier
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapQualifier( value, qualifierId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId )
return wrapValue( value, newAttributes )
end
---Функция для получения сущности (еntity) для текущей страницы
---Подробнее о сущностях см. d:Wikidata:Glossary/ru
---@param id string Идентификатор (типа P18, Q42)
---@return table Таблица, элементы которой индексируются с нуля
local function getEntityFromId( id )
local entity
local wbStatus
if id then
wbStatus, entity = pcall( mw.wikibase.getEntity, id )
else
wbStatus, entity = pcall( mw.wikibase.getEntity )
end
return entity
end
---Внутренняя функция для формирования сообщения об ошибке
---@param key string Ключ элемента в таблице config.errors (например entity-not-found)
---@return void
local function throwError( key )
error( getConfig( 'errors', key ) )
end
---Функция для получения идентификатора сущностей
---@param value table
---@return string
local function getEntityIdFromValue( value )
local prefix = ''
if value[ 'entity-type' ] == 'item' then
prefix = 'Q'
elseif value[ 'entity-type' ] == 'property' then
prefix = 'P'
else
throwError( 'unknown-entity-type' )
end
return prefix .. value[ 'numeric-id' ]
end
---Проверка на наличие специализированной функции в опциях
---@param options table
---@param prefix string
---@return function
local function getUserFunction( options, prefix, defaultFunction )
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then
-- проверка на пустые строки в параметрах или их отсутствие
if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then
throwError( 'unknown-' .. prefix .. '-module' )
end
-- динамическая загруза модуля с обработчиком указанным в параметре
local formatter = require( 'Module:' .. options[ prefix .. '-module' ] )
if formatter == nil then
throwError( prefix .. '-module-not-found' )
end
local fun = formatter[ options[ prefix .. '-function' ] ]
if fun == nil then
throwError( prefix .. '-function-not-found' )
end
return fun
end
return defaultFunction
end
---Выбирает свойства по property id, дополнительно фильтруя их по рангу
---@param context table
---@param options table
---@param propertySelector string
---@return table | nil
local function selectClaims( context, options, propertySelector )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entity is missing' ); end
if not propertySelector then error( 'propertySelector not specified' ); end
local result = WDS.load( options.entityId, propertySelector )
if not result or #result == 0 then
return nil
end
if options.limit and options.limit ~= '' and options.limit ~= '-' then
local limit = tonumber( options.limit, 10 )
while #result > limit do
table.remove( result )
end
end
return result
end
---Функция для получения значения свойства элемента в заданный момент времени.
---@param entityId string
---@param boundaries table Временные границы
---@param propertyIds table<string>
---@param selectors table<string>
---@return table Таблица соответствующих значений свойства
local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end
local results = {}
if not propertyIds or #propertyIds == 0 then
return results
end
for i, propertyId in ipairs( propertyIds ) do
local selector
if selectors ~= nil then
selector = selectors[ i ] or selectors[ propertyId ] or propertyId
else
selector = propertyId
end
local fakeAllClaims = {}
fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' )
if filteredClaims then
for _, claim in pairs( filteredClaims ) do
if not boundaries then
if not claim.qualifiers or not claim.qualifiers.P582 then
table.insert( results, claim.mainsnak )
end
else
local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' )
local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' )
if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and
( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] )
then
table.insert( results, claim.mainsnak )
end
end
end
end
if #results > 0 then
break
end
end
return results
end
---@param context table
---@param propertyId string
---@return table | nil
function p.getTimeBoundariesFromProperty( context, propertyId )
local dateClaims = WDS.filter( context.entity.claims, propertyId )
if not dateClaims or #dateClaims == 0 then
return nil;
end
-- only support exact date so far, but need improvment
local left = nil
local right = nil
for _, claim in pairs( dateClaims ) do
if not claim.mainsnak then
return nil
end
local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
if not left or not right then
return nil
end
return { left, right }
end
---@param context table
---@param propertyIds table<string>
---@return table | nil
function p.getTimeBoundariesFromProperties( context, propertyIds )
for _, propertyId in ipairs( propertyIds ) do
local result = p.getTimeBoundariesFromProperty( context, propertyId );
if result then
return result
end
end
return nil
end
---@param context table
---@param statement table
---@param qualifierId string
---@return table | nil
function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
-- only support exact date so far, but need improvement
local left, right
if statement.qualifiers and statement.qualifiers[ qualifierId ] then
for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do
local boundaries = context.parseTimeBoundariesFromSnak( qualifier )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
end
if not left or not right then
return nil
end
return { left, right }
end
---@param _ table
---@param context table
---@param statement table
---@param qualifierIds table<string>
---@return table | nil
function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds )
if not qualifierIds then
qualifierIds = { 'P582', 'P580', 'P585' }
end
for _, qualifierId in pairs( qualifierIds ) do
local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
if result then
return result
end
end
return nil
end
---@type table<string>
local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' }
---@type table<string>
local getLabelWithLang_DEFAULT_SELECTORS = {
'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]'
}
---Функция для получения метки элемента в заданный момент времени.
---@param context table
---@param options table
---@param entityId string
---@param boundaries table
---@param propertyIds table
---@param selectors table<string>
---@return string, string Текстовая метка элемента, язык метки
local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end
if not entityId then
return nil
end
local langCode = CONTENT_LANGUAGE_CODE
-- name from label
local label
if options.text and options.text ~= '' then
label = options.text
else
if not propertyIds then
propertyIds = getLabelWithLang_DEFAULT_PROPERTIES
selectors = getLabelWithLang_DEFAULT_SELECTORS
end
-- name from properties
local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
for _, result in pairs( results ) do
if result.datavalue and result.datavalue.value then
if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then
label = result.datavalue.value.text
langCode = result.datavalue.value.language
break
elseif result.datavalue.type == 'string' then
label = result.datavalue.value
break
end
end
end
if not label then
label, langCode = mw.wikibase.getLabelWithLang( entityId )
if not langCode then
return nil
end
end
end
return label, langCode
end
---@param context table
---@param options table
---@return string
local function formatPropertyDefault( context, options )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
local claims
if options.property then -- TODO: Почему тут может не быть property?
if options.rank then -- передать настройки ранга из конфига
claims = context.selectClaims( options, options.property .. options.rank )
else
claims = context.selectClaims( options, options.property )
end
end
if claims == nil then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных
-- заявлений в таблице
local formattedClaims = {}
for _, claim in pairs( claims ) do
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
if formattedStatement and formattedStatement ~= '' then
if not options.plain then
formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id )
end
table.insert( formattedClaims, formattedStatement )
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
---Create context
---@param initOptions table
---@return table | nil
local function initContext( initOptions )
local context = {
entityId = initOptions.entityId,
entity = initOptions.entity,
extractCategory = extractCategory,
formatSnak = formatSnak,
formatPropertyDefault = formatPropertyDefault,
formatStatementDefault = formatStatementDefault,
getPropertyInBoundaries = getPropertyInBoundaries,
getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty,
getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties,
getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier,
getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers,
parseTimeFromSnak = p._parseTimeFromSnak,
getLabelWithLang = getLabelWithLang,
wrapSnak = wrapSnak,
wrapStatement = wrapStatement,
wrapQualifier = wrapQualifier,
}
context.cloneOptions = function( options )
local entity = options.entity
options.entity = nil
local newOptions = mw.clone( options )
options.entity = entity
newOptions.entity = entity
newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate()
return newOptions
end
context.formatProperty = function( options )
local func = getUserFunction( options, 'property', context.formatPropertyDefault )
return func( context, options )
end
context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end
context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end
context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end
context.parseTimeBoundariesFromSnak = function( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then
return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision )
end
return nil
end
context.getSourcingCircumstances = function( statement )
return getSourcingCircumstances( statement )
end
context.selectClaims = function( options, propertyId )
return selectClaims( context, options, propertyId )
end
return context
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param options table
---@return string Formatted wikitext.
local function formatProperty( options )
-- Получение сущности по идентификатору
local entity = getEntityFromId( options.entityId )
if not entity then
return -- throwError( 'entity-not-found' )
end
-- проверка на присутсвие у сущности заявлений (claim)
-- подробнее о заявлениях см. d:Викиданные:Глоссарий
if not entity.claims then
return '' --TODO error?
end
-- improve options
options.frame = g_frame
options.entity = entity
options.extends = function( self, newOptions )
return copyTo( newOptions, copyTo( self, {} ) )
end
if options.i18n then
options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) )
else
options.i18n = getConfig( 'i18n' )
end
local context = initContext( options )
return context.formatProperty( options )
end
---Функция для оформления одного утверждения (statement)
---@param context table
---@param options table
---@param statement table
---@return string Formatted wikitext.
function formatStatement( context, options, statement )
if not statement then
error( 'statement is not specified or nil' )
end
if not statement.type or statement.type ~= 'statement' then
throwError( 'unknown-claim-type' )
end
local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault )
return functionToCall( context, options, statement )
end
---@param statement table
---@return table
function getSourcingCircumstances( statement )
if not statement then
error( 'statement is not specified' )
end
local circumstances = {}
if statement.qualifiers and statement.qualifiers.P1480 then
for _, qualifier in pairs( statement.qualifiers.P1480 ) do
if qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid'
and qualifier.datavalue.value
and qualifier.datavalue.value[ 'entity-type'] == 'item'
then
table.insert( circumstances, qualifier.datavalue.value.id )
end
end
end
return circumstances
end
---Функция для оформления одного утверждения (statement)
---@param context table Context.
---@param options table Parameters.
---@param statement table
---@return string Formatted wikitext.
function formatStatementDefault( context, options, statement )
if not context then error( 'context is not specified' ) end
if not options then error( 'options is not specified' ) end
if not statement then error( 'statement is not specified' ) end
local circumstances = context.getSourcingCircumstances( statement )
options.qualifiers = statement.qualifiers
local result = context.formatSnak( options, statement.mainsnak, circumstances )
if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then
local qualifierConfig = getPropertyParams( options.qualifier, nil, {} )
if options.i18n then
qualifierConfig.i18n = options.i18n
end
if qualifierConfig.datatype == 'time' then
qualifierConfig.nolinks = true
end
local qualifierValues = {}
for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do
local snakValue = context.formatSnak( qualifierConfig, qualifierSnak )
if snakValue and snakValue ~= '' then
table.insert( qualifierValues, snakValue )
end
end
if result and result ~= '' and #qualifierValues then
if qualifierConfig.invisible then
result = result .. table.concat( qualifierValues, ', ' )
else
result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')'
end
end
end
if result and result ~= '' and options.references then
result = result .. context.formatRefs( options, statement )
end
return result
end
---Функция для оформления части утверждения (snak)
---Подробнее о snak см. d:Викиданные:Глоссарий
---@param context table Context.
---@param options table Parameters.
---@param snak table
---@param circumstances table
---@return string Formatted wikitext.
function formatSnak( context, options, snak, circumstances )
circumstances = circumstances or {}
local result
if snak.snaktype == 'somevalue' then
if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then
result = options[ 'somevalue' ]
else
result = options.i18n[ 'somevalue' ]
end
elseif snak.snaktype == 'novalue' then
if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then
result = options[ 'novalue' ]
else
result = options.i18n[ 'novalue' ]
end
elseif snak.snaktype == 'value' then
result = formatDatavalue( context, options, snak.datavalue, snak.datatype )
for _, item in pairs( circumstances ) do
if options.i18n[ item ] then
result = options.i18n[ item ] .. result
end
end
else
throwError( 'unknown-snak-type' )
end
if not result or result == '' then
return nil
end
if options.plain then
return result
end
return context.wrapSnak( result, snak.hash )
end
---Функция для оформления объектов-значений с географическими координатами
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatGlobeCoordinate( value, options )
-- проверка на требование в параметрах вызова на возврат сырого значения
if options[ 'subvalue' ] == 'latitude' then -- широты
return value[ 'latitude' ]
elseif options[ 'subvalue' ] == 'longitude' then -- долготы
return value[ 'longitude' ]
elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then
-- если передан параметр nocoord, то не выводить координаты
-- обычно это делается при использовании нескольких карточек на странице
return ''
else
-- в противном случае формируются параметры для вызова шаблона {{coord}}
-- нужно дописать в документации шаблона, что он отсюда вызывается, и что
-- любое изменние его парамеров должно быть согласовано с кодом тут
local coordModule = require( 'Module:Coordinates' )
local globe = options.globe or ''
if globe == '' and value[ 'globe' ] then
local globes = require( 'Module:Wikidata/Globes' )
globe = globes[ value[ 'globe' ] ] or ''
end
local display = 'inline'
if options.display and options.display ~= '' then
display = options.display
elseif ( options.property:upper() == 'P625' ) then
display = 'title'
end
local format = options.format or ''
if format == '' then
format = 'dms'
if value[ 'precision' ] then
local precision = value[ 'precision' ] * 60
if precision >= 60 then
format = 'd'
elseif precision >= 1 then
format = 'dm'
end
end
end
g_frame.args = {
tostring( value[ 'latitude' ] ),
tostring( value[ 'longitude' ] ),
globe = globe,
type = options.type and options.type or '',
scale = options.scale and options.scale or '',
display = display,
format = format,
}
return coordModule.coord(g_frame)
end
end
---Функция для оформления объектов-значений с файлами с Викисклада
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatCommonsMedia( value, options )
local image = value
local caption = ''
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
caption = options[ 'caption' ]
end
if caption ~= '' then
caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } )
end
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]]
image = '[[File:' .. value .. '|frameless'
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border'
end
local size = options[ 'size' ]
if size and size ~= '' then
-- TODO: check localized pixel names too
if not string.match( size, 'px$' ) then
size = size .. 'px'
end
else
size = fileDefaultSize
end
image = image .. '|' .. size
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ]
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]'
if caption ~= '' then
image = image .. '<br>' .. caption
end
else
image = image .. caption .. getCategoryByCode( 'media-contains-markup' )
end
return image
end
---Function for render math formulas
---@param value string Value.
---@param options table Parameters.
---@return string Formatted string.
local function formatMath( value, options )
return options.frame:extensionTag{ name = 'math', content = value }
end
---Функция для оформления внешних идентификаторов
---@param value string
---@param options table
---@return string
local function formatExternalId( value, options )
local formatter = options.formatter
local propertyId = options.property:upper()
if not formatter or formatter == '' then
local isGoodFormat = false
local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' )
if wbStatus and formatRegexStatements then
for _, statement in pairs( formatRegexStatements ) do
if statement.mainsnak.snaktype == 'value' then
local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' )
pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' )
if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' )
or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then
isGoodFormat = true
break
end
end
end
end
if isGoodFormat then
local formatterStatements
wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' )
if wbStatus and formatterStatements then
for _, statement in pairs( formatterStatements ) do
if statement.mainsnak.snaktype == 'value' then
formatter = statement.mainsnak.datavalue.value
break
end
end
end
end
end
if formatter and formatter ~= '' then
local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub
local link = mw.ustring.gsub(
mw.ustring.gsub( formatter, '$1', encodedValue ), '.',
{ [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } )
local title = options.title
if not title or title == '' then
title = '$1'
end
title = mw.ustring.gsub(
mw.ustring.gsub( title, '$1', encodedValue ), '.',
{ [ '[' ] = '(', [ ']' ] = ')' } )
return '[' .. link .. ' ' .. title .. ']'
end
return value
end
---Функция для оформления числовых значений
---@param value table Объект-значение
---@param options table Таблица параметров
---@return string Оформленный текст
local function formatQuantity( value, options )
-- диапазон значений
local amount = string.gsub( value.amount, '^%+', '' )
local lang = mw.language.getContentLanguage()
local langCode = lang:getCode()
local function formatNum( number, sigfig )
local multiplier = ''
if options.countByThousands then
local powers = options.i18n.thousandPowers
local pos = 1
while math.abs( number ) >= 1000 and pos < #powers do
number = number / 1000
pos = pos + 1
end
multiplier = powers[ pos ]
if math.abs( number ) >= 100 then
sigfig = sigfig or 0
elseif math.abs( number ) >= 10 then
sigfig = sigfig or 1
else
sigfig = sigfig or 2
end
else
sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности
end
local iMultiplier = 10^sigfig
number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier
return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier
end
local out = formatNum( tonumber( amount ) )
if value.upperBound then
local diff = tonumber( value.upperBound ) - tonumber( amount )
if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local bound = formatNum( diff, precision )
if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате
local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2
bound = formatNum( diff * 10 ^ digits, precision )
bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 )
end
out = out .. ' ± ' .. bound
end
end
if options.unit and options.unit ~= '' then
if options.unit ~= '-' then
out = out .. ' ' .. options.unit
end
elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then
local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' )
if unitEntityId ~= 'undefined' then
local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
if wbStatus == true and unitEntity then
if unitEntity.claims.P2370 and
unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and
not value.upperBound and
options.siConversion == true
then
local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' )
if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then
-- Если не степени десятки (переводить сантиметры в метры не надо!)
local outValue = tonumber( amount ) * conversionToSiUnit
if outValue > 0 then
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 )
local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 )
out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) )
else
out = formatNum( outValue, 0 )
end
unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' )
wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
end
end
local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, {
'P5061[language:' .. langCode .. ']',
'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']',
'P558[!P282][!P407]'
} )
out = out .. ' ' .. label
end
end
end
return out
end
---Функция для оформления URL
---@param context table
---@param options table
---@param value string
local function formatUrlValue( context, options, value )
if not options.length or options.length == '' then
options.length = 25
end
local moduleUrl = require( 'Module:URL' )
return moduleUrl.formatUrlSingle( context, options, value )
end
local DATATYPE_CACHE = {}
---Get property datatype by ID.
---@param propertyId string Property ID, e.g. 'P123'.
---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'.
local function getPropertyDatatype( propertyId )
if not propertyId or not string.match( propertyId, '^P%d+$' ) then
return nil
end
local cached = DATATYPE_CACHE[ propertyId ]
if cached ~= nil then
return cached
end
local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId )
if wbStatus ~= true or not propertyEntity then
return nil
end
mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' )
DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype
return propertyEntity.datatype
end
---@param datavalue table
---@return function
local function getPlainValueFunction( datavalue, _ )
if datavalue.type == 'wikibase-entityid' then
return function( _, _, value )
return getEntityIdFromValue( value )
end
elseif datavalue.type == 'string' then
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
return function( _, _, value )
return value.text
end
elseif datavalue.type == 'globecoordinate' then
return function( _, _, value )
return value.latitude .. ',' .. value.longitude
end
elseif datavalue.type == 'quantity' then
return function( _, _, value )
return value.amount
end
elseif datavalue.type == 'time' then
return function( _, _, value )
return value.time
end
end
throwError( 'unknown-datavalue-type' )
end
---@param datavalue table
---@param datatype string
---@return function
local function getDefaultValueFunction( datavalue, datatype )
-- вызов обработчиков по умолчанию для известных типов значений
if datavalue.type == 'wikibase-entityid' then
-- Entity ID
return function( context, options, value )
return formatEntityId( context, options, getEntityIdFromValue( value ) )
end
elseif datavalue.type == 'string' then
-- String
if datatype and datatype == 'commonsMedia' then
-- Media
return function( _, options, value )
return formatCommonsMedia( value, options )
end
elseif datatype and datatype == 'external-id' then
-- External ID
return function( _, options, value )
return formatExternalId( value, options )
end
elseif datatype and datatype == 'math' then
-- Math formula
return function( _, options, value )
return formatMath( value, options )
end
elseif datatype and datatype == 'url' then
-- URL
return formatUrlValue
end
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
-- моноязычный текст (строка с указанием языка)
return function( _, options, value )
if options.monolingualLangTemplate == 'lang' then
if value.language == CONTENT_LANGUAGE_CODE then
return value.text
end
return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } }
elseif options.monolingualLangTemplate == 'ref' then
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language }
else
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>'
end
end
elseif datavalue.type == 'globecoordinate' then
-- географические координаты
return function( _, options, value )
return formatGlobeCoordinate( value, options )
end
elseif datavalue.type == 'quantity' then
return function( _, options, value )
return formatQuantity( value, options )
end
elseif datavalue.type == 'time' then
return function( context, options, value )
local moduleDate = require( 'Module:Wikidata/date' )
return moduleDate.formatDate( context, options, value )
end
end
-- во всех стальных случаях возвращаем ошибку
throwError( 'unknown-datavalue-type' )
end
---Функция для оформления значений (value)
---Подробнее о значениях см. d:Wikidata:Glossary/ru
---@param context table
---@param options table
---@param datavalue table
---@param datatype string
---@return string Оформленный текст
function formatDatavalue( context, options, datavalue, datatype )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not datavalue then error( 'datavalue not specified' ); end
if not datavalue.value then error( 'datavalue.value is missing' ); end
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options.plain then
context.formatValueDefault = getPlainValueFunction( datavalue, datatype )
else
context.formatValueDefault = getDefaultValueFunction( datavalue, datatype )
end
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault )
return functionToCall( context, options, datavalue.value )
end
local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000}
---Функция для оформления идентификатора сущности
---@param context table
---@param options table
---@param entityId string
---@return string Оформленный текст
function formatEntityId( context, options, entityId )
-- получение локализованного названия
local boundaries
if options.qualifiers then
boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } )
end
if not boundaries then
boundaries = DEFAULT_BOUNDARIES
end
local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries )
-- определение соответствующей показываемому элементу категории
local category = context.extractCategory( options, { id = entityId } )
-- получение ссылки по идентификатору
local link = mw.wikibase.sitelink( entityId )
if link then
-- ссылка на категорию, а не добавление страницы в неё
if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then
link = ':' .. link
end
if label and not options.rawArticle then
if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then
label = '<span lang="' .. label .. '">' .. label .. '</span>'
end
local a = '[[' .. link .. '|' .. label .. ']]'
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return a .. category
else
return '[[' .. link .. ']]' .. category
end
end
if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId)
-- красная ссылка
-- TODO: разобраться, почему не всегда есть options.frame
local moduleRedLink = require( 'Module:Wikidata/redLink' )
local title = mw.title.new( label )
if title and not title.exists and options.frame then
local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль
local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId)
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' ..
getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return redLink .. category
end
-- TODO: перенести до проверки на существование статьи
local addWdLink = false
if ( not options.format or options.format ~= 'text' )
and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text
then
addWdLink = true
end
-- одноимённая статья уже существует - выводится текст и ссылка на ВД
return moduleRedLink.formatText(label, entityId, addWdLink) .. category
end
-- сообщение об отсутвии локализованного названия
-- not good, but better than nothing
return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@deprecated Use p.formatProperty() instead
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatStatements( frame )
return p.formatProperty( frame )
end
---Получение параметров, которые обычно используются для вывода свойства.
---@param propertyId string
---@param datatype string
---@param params table
function getPropertyParams( propertyId, datatype, params )
local config = getConfig()
-- Различные уровни настройки параметров, по убыванию приоритета
local propertyParams = {}
-- 1. Параметры, указанные явно при вызове
if params then
for key, value in pairs( params ) do
if value ~= '' then
propertyParams[ key ] = value
end
end
end
if toBoolean( propertyParams.plain, false ) then
propertyParams.separator = propertyParams.separator or ', '
propertyParams.conjunction = propertyParams.conjunction or ', '
else
-- 2. Настройки конкретного параметра
if config.properties and config.properties[ propertyId ] then
for key, value in pairs( config.properties[ propertyId ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 3. Указанный пресет настроек
if propertyParams.preset and config.presets and
config.presets[ propertyParams.preset ]
then
for key, value in pairs( config.presets[ propertyParams.preset ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId )
if propertyParams.datatype == nil then
propertyParams.datatype = datatype
end
-- 4. Настройки для типа данных
if datatype and config.datatypes and config.datatypes[ datatype ] then
for key, value in pairs( config.datatypes[ datatype ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 5. Общие настройки для всех свойств
if config.global then
for key, value in pairs( config.global ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
end
return propertyParams
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatProperty( frame )
local args = copyTo( frame.args, {} )
-- проверка на отсутствие обязательного параметра property
if not args.property then
throwError( 'property-param-not-provided' )
end
local override
local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w)
if string.sub( w, 1, 1 ) == '~' then
override = w
end
return ''
end ) )
if override then
args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' )
args.property = propertyId
end
-- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно
local p_frame = frame
while p_frame do
if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then
copyTo( p_frame.args, args, true )
end
if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then
args.entityId = p_frame.args.from
else
args.entityId = mw.wikibase.getEntityIdForCurrentPage()
end
p_frame = p_frame:getParent()
end
args = getPropertyParams( propertyId, nil, args )
local datatype = args.datatype
-- перевод итоговых значений флагов в true/false и добавление значений
-- по умолчанию только в том случае, если они нигде не были указаны ранее
args.plain = toBoolean( args.plain, false )
args.nocat = not args.plain and toBoolean( args.nocat, false )
args.references = not args.plain and toBoolean( args.references, true )
-- если значение передано в параметрах вызова то выводим только его
if args.value and args.value ~= '' then
-- специальное значение для скрытия Викиданных
if args.value == '-' then
return ''
end
local value = args.value
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if args.plain then
return value
end
local context = initContext( args )
-- обработчики по типу значения
local wrapperExtraArgs = {}
if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then
local func = getUserFunction( args, 'value' )
value = func( context, args, value )
elseif datatype == 'commonsMedia' then
value = formatCommonsMedia( value, args )
elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then
wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value )
value = formatExternalId( value, args )
--elseif datatype == 'math' then
-- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag
-- value = formatMath( value, args )
elseif datatype == 'url' then
value = formatUrlValue( context, args, value )
end
-- оборачиваем в тег для JS-функций
if string.match( propertyId, '^P%d+$' ) then
value = mw.text.trim( value )
-- временная штрафная категория для исправления табличных вставок
local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables
if not allowTables
and string.match( value, '<t[dhr][ >]' )
-- and not string.match( value, '<table[ >]' )
-- and not string.match( value, '^%{%|' )
then
value = value .. getCategoryByCode( 'value-contains-table', propertyId )
else
value = wrapStatement( value, propertyId, nil, wrapperExtraArgs )
end
end
return value
end
-- ability to disable loading Wikidata
if args.entityId == '-' then
return ''
end
g_frame = frame
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений)
return formatProperty( args )
end
---Функция проверки на присутствие источника в списке нерекомендованных.
---@param snaks table
---@return boolean
local function isReferenceDeprecated( snaks )
if not snaks then
return false
end
if snaks.P248
and snaks.P248[ 1 ]
and snaks.P248[ 1 ].datavalue
and snaks.P248[ 1 ].datavalue.value.id
then
local entityId = snaks.P248[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
elseif snaks.P1433
and snaks.P1433[ 1 ]
and snaks.P1433[ 1 ].datavalue
and snaks.P1433[ 1 ].datavalue.value.id
then
local entityId = snaks.P1433[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
end
return false
end
---Функция оформления ссылок на источники (reference)
---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru
---
---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context
---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства).
---@param context table
---@param options table
---@param statement table
---@return string Оформленные примечания для отображения в статье
function formatRefs( context, options, statement )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
if not statement then error( 'statement not specified' ); end
if not outputReferences then
return ''
end
---@type string[]
local references = {}
if statement.references then
local hasNotDeprecated = false
local displayCount = 0
for _, reference in pairs( statement.references ) do
if not isReferenceDeprecated( reference.snaks ) then
hasNotDeprecated = true
end
end
for _, reference in pairs( statement.references ) do
local display = true
if hasNotDeprecated then
if isReferenceDeprecated( reference.snaks ) then
display = false
end
end
if displayCount >= 2 then
if options.entityId and options.property then
local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше
local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>'
table.insert( references, moreReferences )
end
break
end
if display == true then
---@type string
local refText = moduleSources.renderReference( g_frame, options.entityId, reference )
if refText and refText ~= '' then
table.insert( references, refText )
displayCount = displayCount + 1
end
end
end
end
return table.concat( references )
end
return p
4558f762f30c6ebfb9f5333dbd7ebda83c6873f2
Модуль:Sources
828
83
177
176
2025-01-31T15:24:23Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
---@alias args table
---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) }
---@alias source { publication: source, [string]: any }
---@alias value: string | { id: string }
---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } }
---@alias snaks table<string, table<number, snak>>
---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks }
---@alias statements table<string, table<number, statement>>
---@alias map { name: string, ids: string[] }[]>
---@type table
local p = {}
---@type table<string, string>
local NORMATIVE_DOCUMENTS = {
Q20754888 = 'Закон Российской Федерации',
Q20754884 = 'Закон РСФСР',
Q20873831 = 'Распоряжение Президента Российской Федерации',
Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации',
Q2061228 = 'Указ Президента Российской Федерации',
}
---@type table<string, string>
local LANG_CACHE = {
Q150 = 'fr',
Q188 = 'de',
Q1321 = 'es',
Q1860 = 'en',
Q652 = 'it',
Q7737 = 'ru',
Q8798 = 'uk',
}
---@type map
local PROPERTY_MAP = {
{ name = 'sourceId', ids = { 'P248', 'P805' } },
{ name = 'lang', ids = { 'P407', 'P364' } },
{ name = 'author', ids = { 'P50', 'P2093' } },
{ name = 'part', ids = { 'P958', 'P1810' } },
{ name = 'title', ids = { 'P1476' } },
{ name = 'subtitle', ids = { 'P1680' } },
{ name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } },
{ name = 'editor', ids = { 'P98' } },
{ name = 'translator', ids = { 'P655' } },
{ name = 'publication-id', ids = { 'P1433' } },
{ name = 'edition', ids = { 'P393' } },
{ name = 'publisher', ids = { 'P123' } },
{ name = 'place', ids = { 'P291' } },
{ name = 'volume', ids = { 'P478' } },
{ name = 'issue', ids = { 'P433' } },
{ name = 'dateOfCreation', ids = { 'P571' } },
{ name = 'dateOfPublication', ids = { 'P577' } },
{ name = 'pages', ids = { 'P304' } },
{ name = 'numberOfPages', ids = { 'P1104' } },
{ name = 'tirage', ids = { 'P1092' } },
{ name = 'isbn', ids = { 'P212', 'P957' } },
{ name = 'issn', ids = { 'P236' } },
-- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references
{ name = 'docNumber', ids = { 'P1545' } },
{ name = 'type', ids = { 'P31' } },
{ name = 'arxiv', ids = { 'P818' } },
{ name = 'doi', ids = { 'P356' } },
{ name = 'pmid', ids = { 'P698' } },
}
-- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier
---@type map
local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP )
---@type string[]
local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' }
---@type string
local i18nDefaultLanguage = mw.language.getContentLanguage():getCode()
p.i18nDefaultLanguage = i18nDefaultLanguage
---@type string
local i18nEtAlDefault = ' et al.'
---@type table<string, string>
local i18nEtAl = {
ru = ' и др.',
uk = ' та ін.',
}
---@type table<string, string>
local i18nEditors = {
fr = '',
de = 'Hrsg.: ',
es = '',
en = '',
it = '',
ru = 'под ред. ',
uk = 'за ред. ',
}
---@type table<string, string>
local i18nTranslators = {
fr = '',
de = '',
es = '',
en = '',
it = '',
ru = 'пер. ',
uk = 'пер. ',
}
---@type table<string, string>
local i18nVolume = {
de = 'Vol.',
fr = 'Vol.',
es = 'Vol.',
en = 'Vol.',
it = 'Vol.',
ru = 'Т.',
uk = 'Т.',
}
---@type table<string, string>
local i18nIssue = {
en = 'Iss.',
ru = 'вып.',
uk = 'вип.',
}
---@type table<string, string>
local i18nPages = {
fr = 'P.',
de = 'S.',
es = 'P.',
en = 'P.',
it = 'P.',
ru = 'С.',
uk = 'С.',
}
---@type table<string, string>
local i18nNumberOfPages = {
en = 'p.',
ru = 'с.',
}
---@type table<string, string>
local i18nTirage = {
en = 'ed. size: %d',
ru = '%d экз.',
}
---@param args args
---@return source
local function getFilledArgs( args )
---@type source
local data = {}
for key, value in pairs( args ) do
if mw.text.trim( value ) ~= '' then
if key == 1 then
key = 'sourceId'
end
data[ key ] = mw.text.trim( value )
end
end
return data
end
---Returns formatted pair {Family name(s), First name(s)}
---@param fullName string
---@return table<number, string>
local function tokenizeName( fullName )
local space = '%s+' -- matches single or more spacing character
local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot
local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot
local surnamePrefixes = { 'ван', 'van', 'де', 'de' }
local nm, nm2, srn, srn2, pref
fullName = ' ' .. fullName .. ' '
fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' )
fullName = mw.text.trim( fullName )
-- Surname, Name
local pattern = '^' .. surname .. ',' .. space .. name .. '$'
srn, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Surname, Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '.' }
end
end
-- Surname, Name Name
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$'
srn, nm, nm2 = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Surname Surname, Name
pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$'
srn, srn2, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn .. ' ' .. srn2,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Name Name Surname
pattern = '^' .. name .. space .. name .. space .. surname .. '$'
nm, nm2, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Name Name prefix Surname
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$'
nm, nm2, pref, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Surname, Name Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, nm2, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Name{1,4} Surname
for k = 1, 4 do
pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 1, k do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ k + 1 ],
table.concat( matched, '. ', 1, k ) .. '.'
}
end
end
-- Surname Name{1,4}
for k = 1, 4 do
pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 2, k + 1 do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ 1 ],
table.concat( matched, '. ', 2, k + 1 ) .. '.'
}
end
end
return { fullName }
end
---@param fullName string | nil
---@return string | nil
local function personNameToAuthorName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 1 ] .. ' ' .. tokenized[ 2 ]
end
---@param fullName string | nil
---@return string | nil
local function personNameToResponsibleName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 2 ] .. ' ' .. tokenized[ 1 ]
end
---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean }
---@type options
local options_commas = {
separator = ', ',
conjunction = ', ',
format = function( data ) return data end,
nolinks = false,
preferids = false,
short = false,
}
---@type options
local options_commas_short = mw.clone( options_commas )
options_commas_short.short = true
---@type options
local options_commas_it_short = mw.clone( options_commas_short )
options_commas_it_short.format = function( data ) return "''" .. data .. "''" end
---@type options
local options_commas_nolinks = mw.clone( options_commas )
options_commas_nolinks.nolinks = true
---@type options
local options_citetypes = {
separator = ' ',
conjunction = ' ',
format = function( data ) return 'citetype_' .. data end,
nolinks = true ,
preferids = true,
short = false,
}
---@type options
local options_commas_authors = mw.clone( options_commas )
options_commas_authors.format = personNameToAuthorName
---@type options
local options_commas_responsible = mw.clone( options_commas )
options_commas_responsible.format = personNameToResponsibleName
---@type options
local options_ids = {
separator = '; ',
conjunction = '; ',
format = function( id ) return id end,
nolinks = true,
preferids = false,
short = false,
}
---@type options
local options_arxiv = mw.clone( options_ids )
options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end
---@type options
local options_doi = mw.clone( options_ids )
options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end
---@type options
local options_issn = mw.clone( options_ids )
options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end
---@type options
local options_pmid = mw.clone( options_ids )
options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end
---@param str string | nil
---@return boolean
local function isEmpty( str )
return not str or #str == 0
end
---@param allQualifiers snaks
---@param qualifierPropertyId string
---@return string | nil
local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId )
if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then
return nil
end
---@type table<number, snak>
local propertyQualifiers = allQualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if ( qualifier
and qualifier.datatype == 'string'
and qualifier.datavalue
and qualifier.datavalue.type == 'string'
and qualifier.datavalue.value ~= ''
) then
return qualifier.datavalue.value
end
end
return nil
end
---@param data table
---@param resultProperty string
---@return void
local function appendImpl_toTable( data, resultProperty )
if not data[ resultProperty ] then
data[ resultProperty ] = {}
elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then
data[ resultProperty ] = { data[ resultProperty ] }
end
end
---@param datavalue table
---@param qualifiers snaks
---@param data table
---@param propertyName string
---@param options table
local function appendImpl( datavalue, qualifiers, data, propertyName, options )
data[ propertyName ] = data[ propertyName ] or {}
if propertyName == 'issn' then
table.insert( data[ propertyName ], datavalue.value )
elseif propertyName == 'url' or datavalue.type == 'url' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'string' then
local value = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not value then
value = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
if not value then
value = datavalue.value
if options.format then
value = options.format( value )
end
end
appendImpl_toTable(data, propertyName)
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
if pos then
table.insert( data[ propertyName ], tonumber(pos), value )
else
table.insert( data[ propertyName ], value )
end
elseif datavalue.type == 'monolingualtext' then
local value = datavalue.value.text
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'quantity' then
local value = datavalue.value.amount
if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then
value = mw.ustring.sub( value , 2 )
end
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'wikibase-entityid' then
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
local value = datavalue.value
appendImpl_toTable(data, propertyName)
local label = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not label then
label = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
local toInsert = {
id = value.id,
label = label
}
if pos and tonumber( pos ) then
table.insert( data[ propertyName ], tonumber( pos ), toInsert )
else
table.insert( data[ propertyName ], toInsert )
end
elseif datavalue.type == 'time' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], tostring( value.time ) )
end
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getAllStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getBestStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param projectToCheck string?
---@return string | nil
local function getSitelink( entityId, projectToCheck )
---@type boolean, string
local wbStatus, sitelink
if projectToCheck then
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck )
else
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId )
end
if not wbStatus then
return nil
end
return sitelink
end
---@param args any[]
---@return any | nil
local function coalesce( args )
for _, arg in pairs( args ) do
if not isEmpty( arg ) then return arg end
end
return nil
end
---@param value any
---@return string | nil
local function getSingle( value )
if type( value ) == 'string' then
return tostring( value )
elseif type( value ) == 'table' then
if value.id then
return tostring( value.id )
end
for _, tableValue in pairs( value ) do
return getSingle( tableValue )
end
end
return nil
end
---@param langEntityId string
---@return string | nil
local function getLangCode( langEntityId )
if not langEntityId then
return nil
end
langEntityId = getSingle( langEntityId )
if not string.match( langEntityId, '^Q%d+$' ) then
return langEntityId
end
local cached = LANG_CACHE[ langEntityId ]
if cached then
if cached == '' then
return nil
end
return cached
end
local claims = getBestStatements( langEntityId, 'P424' )
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
then
LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value
return claim.mainsnak.datavalue.value
end
end
LANG_CACHE[ langEntityId ] = ''
return nil
end
---@param entityId string
---@param propertyId string
---@param data source
---@param propertyName string
---@param options table?
---@return void
local function appendEntitySnaks( entityId, propertyId, data, propertyName, options )
options = options or {}
-- do not populate twice
if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then
return
end
local statements = getBestStatements( entityId, propertyId )
if propertyName == 'author' then
data[ propertyId ] = true
end
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
if propertyId == 'P1680' then -- if there is a default language
for _, statement in pairs( statements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.language == lang
then
--found default language string
appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options )
return
end
end
end
for _, statement in pairs( statements ) do
if statement and statement.mainsnak and statement.mainsnak.datavalue then
appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options )
if propertyName == 'publication-id' and statement.qualifiers then
data[ 'publication-qualifiers' ] = statement.qualifiers
end
end
end
end
---@param claims table<number, statement>
---@param qualifierPropertyId string
---@param result table
---@param resultPropertyId string
---@param options table
---@return void
local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options )
-- do not populate twice
if not claims or result[ resultPropertyId ] then
return
end
for _, claim in pairs( claims ) do
if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then
---@type table<number, snak>
local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if qualifier and qualifier.datavalue then
appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options )
end
end
end
end
end
---@param entityId string
---@param propertyId string
---@param value any
---@return table<number, statement>
local function findClaimsByValue( entityId, propertyId, value )
local result = {}
local claims = getAllStatements( entityId, propertyId )
for _, claim in pairs( claims ) do
if ( claim.mainsnak and claim.mainsnak.datavalue ) then
local datavalue = claim.mainsnak.datavalue
if ( datavalue.type == "string" and datavalue.value == value ) or
( datavalue.type == "wikibase-entityid" and
datavalue.value[ "entity-type" ] == "item" and
tostring( datavalue.value.id ) == value )
then
table.insert( result, claim )
end
end
end
return result
end
---@param entityId string
---@param typeEntityId string
---@return boolean
local function isInstanceOf( entityId, typeEntityId )
return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil
end
---@param entityId string
---@param typeEntityIds string[]
---@return string
---@todo Rewrite
local function getFirstType( entityId, typeEntityIds )
for _, typeEntityId in pairs( typeEntityIds ) do
if isInstanceOf( entityId, typeEntityId ) then
return typeEntityId
end
end
return nil
end
---@param snaks snaks
---@param data source
---@param map map
---@return void
local function populateDataFromSnaks( snaks, data, map )
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
if not data[ parameterName ] and snaks[ propertyId ] then
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
for _, snak in pairs( snaks[ propertyId ] ) do
if snak and snak.datavalue then
appendImpl( snak.datavalue, {}, data, parameterName, options )
end
end
end
end
end
end
---@param entityId string | nil
---@param data source
---@param map map
---@return void
local function populateDataFromEntity( entityId, data, map )
if not data.title then
if not isEmpty( entityId ) then
local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end }
appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks )
else
appendEntitySnaks( entityId, 'P1476', data, 'title', {} )
end
appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} )
end
local bookSeriesStatements = getBestStatements( entityId, 'P361' )
for _, statement in pairs( bookSeriesStatements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.id
then
local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id
if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then
appendImpl_toTable( data, 'bookSeries' )
table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } )
appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} )
appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} )
end
end
end
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
appendEntitySnaks( entityId, propertyId, data, parameterName, options )
end
end
end
---@param data source
---@return void
local function expandPublication( data )
if not data[ 'publication-id' ] then
return
end
local publicationId = getSingle( data[ 'publication-id' ] )
data.publication = {}
for key, value in pairs( data ) do
if not string.match( key, '^publication-' ) then
data.publication[ key ] = value
end
end
data.publication.sourceId = publicationId
data.publication.title = data[ 'publication-title' ]
data.publication.subtitle = data[ 'publication-subtitle' ]
if data[ 'publication-qualifiers' ] then
populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP )
end
populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP )
if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then
data.publication.title = data.publication.title[ 1 ]
end
if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then
data.publication.subtitle = data.publication.subtitle[ 1 ]
end
for key, value in pairs( data.publication ) do
if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then
data[ key ] = value
end
end
end
---@param data source
---@return void
local function expandBookSeries( data )
local bookSeries = data.bookSeries
if not bookSeries then
return
end
-- use only first one
if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then
data.bookSeries = bookSeries[ 1 ]
bookSeries = data.bookSeries
end
if not bookSeries or not bookSeries.id then
return
end
appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} )
appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} )
appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} )
end
---@param entityId string
---@return string | nil
local function getNormativeTitle( entityId )
local possibleTypeIds = {}
for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do
table.insert( possibleTypeIds, typeId )
end
local foundTypeId = getFirstType( entityId, possibleTypeIds )
if foundTypeId then
return NORMATIVE_DOCUMENTS[ foundTypeId ]
end
return nil
end
---@param urls table<number, string> | string
---@param text string
---@return string
local function wrapInUrl( urls, text )
local url = getSingle( urls )
if string.sub( url, 1, 1 ) == ':' then
return '[[' .. url .. '|' .. text .. ']]'
else
return '[' .. url .. ' ' .. text .. ']'
end
end
---@param entityId string
---@param lang string
---@return string
local function getElementLink( entityId, lang )
local sitelink = getSitelink( entityId, nil )
if sitelink then
return ':' .. sitelink
end
if lang ~= 'mul' then
-- link to entity in source language
sitelink = getSitelink( entityId, lang .. 'wiki' )
if sitelink then
return ':' .. lang .. ':' .. sitelink
end
end
return ':d:' .. entityId
end
---@param entityId string
---@param lang string
---@return string
local function getLabel( entityId, lang )
local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang )
if not wbStatus then
return ''
end
if label and label ~= '' then
return label
end
wbStatus, label = pcall( mw.wikibase.getLabel, entityId )
if not wbStatus then
return ''
end
return label or ''
end
---@param lang string
---@param entityId string
---@param customTitle string
---@param options table
local function renderLink( lang, entityId, customTitle, options )
if not entityId then
error( 'entityId is not specified' )
end
if type( entityId ) ~= 'string' then
error( 'entityId is not string, but ' .. type( entityId ) )
end
if type( customTitle or '' ) ~= 'string' then
error( 'customTitle is not string, but ' .. type( customTitle ) )
end
local title = customTitle
-- ISO 4
if isEmpty( title ) then
local propertyStatements = getBestStatements( entityId, 'P1160' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' )
break
end
end
end
-- official name P1448
-- short name P1813
if isEmpty( title ) and options.short then
local propertyStatements = getBestStatements( entityId, 'P1813' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' )
break
end
end
end
-- person name P1559
-- labels
if isEmpty( title ) then
title = getLabel( entityId, lang )
-- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' )
end
local actualText = title or '\'\'(untranslated)\'\''
local link = getElementLink( entityId, lang )
return wrapInUrl( link, actualText )
end
---@param lang string
---@param value value
---@param options options
---@return string
local function asString( lang, value, options )
if type( value ) == 'string' then
return options.format( value )
end
if type( value ) ~= 'table' then
return options.format( '(unknown type)' )
end
if value.id then
-- this is link
if type( value.label or '' ) ~= 'string' then
mw.logObject( value, 'error value' )
error( 'label of table value is not string but ' .. type( value.label ) )
end
local title
if options.preferids then
title = value.id
elseif options.nolinks then
title = value.label or getLabel( value.id, lang )
else
title = renderLink( lang, value.id, value.label, options )
end
if title == '' then
title = "''(untranslated title)''"
end
return options.format( title )
end
local resultList = {}
for _, tableValue in pairs( value ) do
table.insert( resultList, asString( lang, tableValue, options ) )
end
return mw.text.listToText( resultList, options.separator, options.conjunction )
end
---@param entityId string
---@param data source
---@return source
local function populateSourceDataImpl( entityId, data, map )
local wsLink = getSitelink( entityId, 'ruwikisource' )
if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then
data.url = ":ru:s:" .. wsLink
end
populateDataFromEntity( entityId, data, map )
local normativeTitle = getNormativeTitle( entityId )
if normativeTitle then
local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" )
y, m, d = tonumber( y ),tonumber( m ), tonumber( d )
local title = asString( 'ru', data.title, options_commas_nolinks )
local docNumber = getSingle( data.docNumber )
data.title = {
normativeTitle ..
" от " .. tostring( d ) .. " " .. monthGen[ m ] .. " " .. tostring( y ) .. " г." ..
( docNumber and ( " № " .. docNumber ) or '' ) ..
' «' .. title.. '»'
}
end
if not data.title then
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
local label = getLabel( entityId, lang )
if label ~= '' then
data.title = { label }
end
end
return data
end
---@param entityId string
---@param propertyId string
---@param data source
---@return void
local function expandSpecialsQualifiers( entityId, propertyId, data )
local statements = getBestStatements( entityId, propertyId )
for _, statement in pairs( statements ) do
populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP )
end
end
---Expand special types of references when additional data could be found in OTHER entity properties
---@param data source
---@return void
local function expandSpecials( data )
if not data.entityId then
return
end
if data.sourceId == 'Q36578' then
-- Gemeinsame Normdatei -- specified by P227
appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } )
appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } )
data.year = '2012—2016'
expandSpecialsQualifiers( data.entityId, 'P227', data )
elseif data.sourceId == 'Q15222191' then
-- BNF -- specified by P268
appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P268', data )
elseif data.sourceId == 'Q54919' then
-- VIAF -- specified by P214
appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P214', data )
else
-- generic property search
for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do
if sourceClaim.mainsnak.snaktype == 'value' then
local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id
for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do
if sourcePropertyClaim.mainsnak.snaktype == 'value' then
appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', {
format = function( id )
return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' )
end
} )
expandSpecialsQualifiers( data.entityId, sourcePropertyId, data )
break
end
end
end
end
end
-- do we have appropriate record in P1433 ?
local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId )
if claims and #claims ~= 0 then
for _, claim in pairs( claims ) do
populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
end
end
end
---@param text string
---@param tip string
---@return string
local function toTextWithTip( text, tip )
return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>'
end
---@param lang string
---@param placeId string
---@return string
local function getPlaceName( placeId, lang )
-- ГОСТ Р 7.0.12—2011
if lang == 'ru' then
if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end
if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end
if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end
if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end
end
return nil
end
---@param data source
---@param lang string
---@return void
local function preprocessPlace( data, lang )
if not data.place then
return
end
---@type table<number, string>
local newPlace = {}
for index, place in pairs( data.place ) do
if place.id then
local newPlaceStr = getPlaceName( place.id, lang )
if newPlaceStr then
newPlace[ index ] = newPlaceStr
else
newPlace[ index ] = getLabel( place.id, lang )
end
else
newPlace[ index ] = place
end
end
data.place = newPlace
end
---@param entityId string
---@param lang string
---@param providedLabel string | nil
---@param options options
---@return string
local function getPersonNameAsLabel( entityId, lang, providedLabel, options )
-- would custom label provided we don't need to check entity at all
if not isEmpty( providedLabel ) then
return options.format( providedLabel )
end
if lang == 'mul' then
lang = i18nDefaultLanguage
end
---@type string | nil
local personName = getLabel( entityId, lang )
if isEmpty( personName ) then
return '\'\'(not translated to ' .. lang .. ')\'\''
end
if not isInstanceOf( entityId, 'Q5' ) then
return personName
end
return options.format( personName )
end
---@param entityId string
---@param lang string
---@param customLabel string | nil
---@param options options
---@return string
local function getPersonNameAsWikitext( entityId, lang, customLabel, options )
local personName = getPersonNameAsLabel( entityId, lang, customLabel, options )
local link = getElementLink( entityId, lang )
return wrapInUrl( link, personName )
end
---@param value value
---@param lang string
---@param options options
---@return string
local function getPeopleAsWikitext( value, lang, options )
if type( value ) == 'string' then
return options.format( value )
elseif type( value ) == 'table' then
if value.id then
-- this is link
if options.preferids then
return tostring( value.id )
else
if options.nolinks then
return getPersonNameAsLabel( value.id, lang, value.label, options )
else
return getPersonNameAsWikitext( value.id, lang, value.label, options )
end
end
end
local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544)
local resultList = {}
for _, tableValue in pairs( value ) do
local nextWikitext = getPeopleAsWikitext( tableValue, lang, options )
if not isEmpty( nextWikitext ) then
table.insert( resultList, nextWikitext )
if #resultList == maxAuthors + 1 then
-- keep one more to indicate that there are too many
break
end
end
end
local resultWikitext = ''
for i, wikitext in pairs( resultList ) do
if i == maxAuthors + 1 then
resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault )
break
end
if i ~= 1 then
resultWikitext = resultWikitext .. ', '
end
resultWikitext = resultWikitext .. wikitext
end
return resultWikitext
end
return '' -- options.format( '(unknown type)' )
end
---@param lang string
---@param data source
---@return string
local function generateAuthorLinks( lang, data )
local result = ''
if data.author then
result = getPeopleAsWikitext( data.author, lang, options_commas_authors )
result = '<i class="wef_low_priority_links">' .. result .. '</i> '
end
return result
end
---@param lang string
---@param data source
---@param conjunction string
---@param propertyName string
---@param urlPropertyName string?
---@return string
local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName )
if not data[ propertyName ] then
return ''
end
local out
if urlPropertyName and data[ urlPropertyName ] then
out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) )
else
out = asString( lang, data[ propertyName ], options_commas )
end
if not out or out == '' then
return ''
end
return conjunction .. out
end
---@param lang string
---@param data source
---@return string
local function appendTitle( lang, data )
local conjunction = ''
local result = ''
if data.part then
result = result .. appendProperty( lang, data, '', 'part', 'parturl' )
conjunction = ' // '
end
return result .. appendProperty( lang, data, conjunction, 'title', 'url' )
end
---@param lang string
---@return string
local function appendLanguage( lang )
if lang == i18nDefaultLanguage then
return ''
end
---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) }
local langs = require( 'Module:Languages' )
return langs.list_ref( p.currentFrame:newChild{ args = { lang } } )
end
---@param lang string
---@param data source
---@return string
local function appendSubtitle( lang, data )
return appendProperty( lang, data, ': ', 'subtitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendOriginalTitle( lang, data )
return appendProperty( lang, data, ' = ', 'originaltitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublication( lang, data )
if not data.publication then
return ''
end
local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short )
if data.publication.subtitle and data.publication.subtitle ~= '' then
result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short )
end
return result
end
---@param lang string
---@param data source
---@return string
local function appendEditor( lang, data )
if not data.editor and not data.translator then
return ''
end
local result = ' / '
if data.editor then
local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible )
if data.translator then
result = result .. ', '
end
end
if data.translator then
local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible )
end
return result
end
---@param lang string
---@param data source
local function appendEdition( lang, data )
return appendProperty( lang, data, ' — ', 'edition', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublicationData( lang, data )
if not data.place and not data.publisher and not data.year then
return ''
end
local result = ' — '
if data.place then
result = result .. asString( lang, data.place, options_commas_short )
if data.publisher or data.year then
result = result .. ': '
end
end
if data.publisher then
result = result .. asString( lang, data.publisher, options_commas_short )
if data.year then
result = result .. ', '
end
end
if data.year then
result = result .. asString( lang, data.year, options_commas )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendVolumeAndIssue( lang, data )
if not data.volume and not data.issue then
return ''
end
local result = ' — '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.volume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'volume', nil )
result = result ..appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'issue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'issue', nil )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendPages( lang, data )
if not data.pages then
return ''
end
local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ]
local strPages = asString( lang, data.pages, options_commas )
strPages = mw.ustring.gsub( strPages, '[-—]', '—' )
return ' — ' .. letter .. ' ' .. strPages .. '.'
end
---@param lang string
---@param data source
---@return string
local function appendNumberOfPages( lang, data )
if not data.numberOfPages then
return ''
end
local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ]
return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. ' ' .. letter
end
---@param lang string
---@param data source
---@return string
local function appendBookSeries( lang, data )
if not data.bookSeries then
return ''
end
local result = appendProperty( lang, data, ' — (', 'bookSeries', nil )
if data.bookSeriesVolume or data.bookSeriesIssue then
result = result .. '; '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.bookSeriesVolume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'bookSeriesVolume', nil )
result = result .. appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'bookSeriesIssue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'bookSeriesIssue', nil )
end
end
result = result .. ')'
return result
end
---@param lang string
---@param data source
---@return string
local function appendTirage( lang, data )
if not data.tirage then
return ''
end
local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ]
---@type options
local optionsTirage = {
separator = '; ',
conjunction = '; ',
format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end,
short = false,
nolinks = false,
preferids = false,
}
return ' — ' .. asString( lang, data.tirage, optionsTirage )
end
---@param lang string
---@param value string | nil
---@param options options
---@param prefix string?
---@return string
local function appendIdentifier( lang, value, options, prefix )
if not value then
return ''
end
return ' — ' .. ( prefix or '' ) .. asString( lang, value, options )
end
---@param result string
---@param lang string
---@param data source
---@return string
local function wrapSourceId( result, lang, data )
if not data.sourceId then
return result
end
local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown'
return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>'
end
---@param data source
---@return string
local function appendAccessDate( data )
if not data.accessdate then
return ''
end
local date = getSingle( data.accessdate )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local y, m, d = mw.ustring.match( date, pattern )
y, m, d = tonumber( y ), tonumber( m ), tonumber( d )
local date_str = ( d > 0 and ' ' .. tostring( d ) or '' )
.. ( m > 0 and ' ' .. monthGen[ m ] or '' )
.. ( y > 0 and ' ' .. tostring( y ) or '' )
return " <small>Проверено" .. date_str .. ".</small>"
end
---@param data source
---@param lang string
---@return void
local function populateUrl( data, lang )
if data.sourceId and not data.url then
local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' )
if sitelink then
data.url = ':' .. lang .. ':s:' .. sitelink
end
end
end
---@param data source
---@return void
local function populateYear( data )
if not data.year and data.dateOfPublication then
local date = getSingle( data.dateOfPublication )
data.year = mw.ustring.sub( date, 2, 5 )
end
if not data.year and data.dateOfCreation then
local date = getSingle( data.dateOfCreation )
data.year = mw.ustring.sub( date, 2, 5 )
end
end
---@param data source
---@return void
local function populateTitle( data )
data.title = data.title or getSingle( data.url )
end
---@param data source
---@return string
local function renderSource( data )
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
preprocessPlace( data, lang )
populateUrl( data, lang )
populateTitle( data )
if not data.title then
return ''
end
populateYear( data )
local result = generateAuthorLinks( lang, data )
result = result .. appendTitle( lang, data )
result = result .. appendLanguage( lang )
result = result .. appendSubtitle( lang, data )
result = result .. appendOriginalTitle( lang, data )
result = result .. appendPublication( lang, data )
result = result .. '<span class="wef_low_priority_links">'
result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution
result = result .. appendEdition( lang, data )
result = result .. appendPublicationData( lang, data )
result = result .. appendVolumeAndIssue( lang, data )
result = result .. appendPages( lang, data )
result = result .. appendNumberOfPages( lang, data )
result = result .. appendBookSeries( lang, data )
result = result .. appendTirage( lang, data )
result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' )
result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' )
result = result .. appendIdentifier( lang, data.doi, options_doi, nil )
result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil )
result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil )
result = result .. appendAccessDate( data )
result = result .. '</span>'
return wrapSourceId( result, lang, data )
end
---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания
---@param snaks snaks
---@return string | nil
local function renderReferenceImpl( data, snaks )
-- не показывать источники с "импортировано из"
if snaks.P143 then
return nil
end
-- забрать данные из reference
populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
expandSpecials( data )
populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP )
expandPublication( data )
expandBookSeries( data )
if next( data ) == nil then
return nil
end
local rendered = renderSource( data )
if mw.ustring.len( rendered ) == 0 then
return nil
end
if data.ref then
local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' )
rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>'
end
return rendered
end
---@param frame frame
---@param currentEntityId string | { id: string }
---@param reference table{ snaks: snaks }
---@return string | nil
function p.renderSource( frame, currentEntityId, reference )
reference = reference or { snaks = {} }
p.currentFrame = frame
local data = getFilledArgs( frame.args or {} )
populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
if not currentEntityId then
data.entityId = mw.wikibase.getEntityIdForCurrentPage()
elseif type( currentEntityId ) == 'string' then
data.entityId = currentEntityId
elseif type( currentEntityId ) == 'table' and currentEntityId.id then
data.entityId = currentEntityId.id
end
---@type string
local rendered = renderReferenceImpl( data, reference.snaks or {} )
if not rendered then
return ''
end
return rendered
end
---@param frame frame
---@param currentEntityId string
---@param reference table
---@return string
function p.renderReference( frame, currentEntityId, reference )
local rendered = p.renderSource( frame, currentEntityId, reference )
if not rendered or rendered == '' then
return ''
end
-- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет
-- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши.
return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]'
end
---@param frame frame
---@return string | nil
function p.testPersonNameToAuthorName( frame )
return personNameToAuthorName( frame.args[ 1 ] )
end
---@param frame frame
---@return string | nil
function p.testPersonNameToResponsibleName( frame )
return personNameToResponsibleName( frame.args[ 1 ] )
end
return p
752a204827a41ecd6cf518bdb22da12718bca2ec
Модуль:WikidataSelectors
828
84
179
178
2025-01-31T15:24:24Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local i18n = {
["errors"] = {
["rank-not-valid"] = "Некорретное значение приоритета (rank)",
["cant-parse-condition"] = "Не удалось разобрать условие"
}
}
local validRanks = {
'best',
'preferred',
'normal',
'deprecated'
}
--[[
Internal function for error message
Input: key in errors table
Output: error message
]]
local function throwError( key )
error( i18n.errors[key] )
end
local p = {}
--[[
Load property and filter statements
Input: entityId, selector string
Output: filtered statements table
]]
function p.load( entityId, propertySelector )
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
return nil
end
propertyId = string.upper( propertyId )
local allStatements = {}
allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
return p.filter( allStatements, propertySelector )
end
--[[
Parse selectors and filter statements
Input: statements table, selector string
Output: filtered statements table
]]
function p.filter( allClaims, propertySelector )
propertySelector = mw.text.trim( propertySelector )
-- Get property ID from selector
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
propertyId = ''
end
local initPos = #propertyId + 1
propertyId = string.upper( propertyId )
if ( not allClaims ) then
return nil
end
local allPropertyClaims = allClaims[propertyId]
if ( not allPropertyClaims ) then
return nil
end
-- Gathering rules
local rules = p.matchSelectors( propertySelector, initPos )
-- If there is no rank filter, than default rank is 'best'
local isRanked = false
for i, subRules in ipairs( rules ) do
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
isRanked = true
break
end
end
end
if not isRanked then
table.insert( rules, 1, { { type = 'rank', value = 'best' } } )
end
-- Execute rules
allPropertyClaims = p.applyRules( allPropertyClaims, rules )
return allPropertyClaims
end
--[[
Match and gather selector rules
Input: string with selectors rules, start position
Output: rules table
]]
function p.matchSelectors( selectorsString, initPos )
local rules = {}
local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*'
local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$'
if not initPos then
initPos = 1
end
local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
while rawRule do
initPos = initPos + #rawRule
rule = mw.ustring.match( rawRule, rulePattern )
rule = mw.text.trim( rule )
local subRules = mw.text.split( rule, '%s*,%s*' )
local commands = {}
local comm
for i, subRule in ipairs( subRules ) do
local isInversed = false
if mw.ustring.match( subRule, '^!' ) then
isInversed = true
subRule = mw.ustring.match( subRule, '^!%s*(.+)$' )
end
-- p123[1]
if mw.ustring.match( subRule, '^%d+$' ) then
table.insert( commands, {
type = 'position',
value = subRule,
inversed = isInversed
} )
-- p123[rank:preferred]
elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then
rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' )
table.insert( commands, {
type = 'rank',
value = rank,
inversed = isInversed
} )
-- p123[language:xx]
elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = isInversed
} )
-- p123[language!:xx]
elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = not isInversed
} )
-- p123[min]
elseif mw.ustring.match( subRule, '^min$' ) then
table.insert( commands, { type = 'value_min' } )
-- p123[max]
elseif mw.ustring.match( subRule, '^max$' ) then
table.insert( commands, { type = 'value_max' } )
-- p123[min:p456]
elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_min',
qualifier = value
} )
-- p123[max:p456]
elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_max',
qualifier = value
} )
-- p123[unit:q789]
elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = isInversed
} )
-- p123[unit!:q789]
elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = not isInversed
} )
-- p123[p456]
elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then
qualifier = mw.ustring.match( subRule, '^[Pp]%d+' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = nil,
inversed = isInversed
} )
-- p123[p456:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' )
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = isInversed
} )
-- p123[p456!:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' )
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = not isInversed
} )
-- p123[q456]
elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then
value = mw.ustring.match( subRule, '^[Qq]%d+' )
table.insert( commands, {
type = 'value',
value = value,
inversed = isInversed
} )
else
throwError( 'cant-parse-condition' )
end
end
if #commands then
table.insert( rules, commands )
end
rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
end
return rules
end
--[[
Intercept statements with selector rules
Input: statements table, selector rules
Output: filtered statements table
]]
function p.applyRules( claims, rules )
for i, subRules in ipairs( rules ) do
local newClaims = {}
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'language' then
table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'unit' then
table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'position' then
table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier' then
table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier_min' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) )
elseif rule['type'] == 'qualifier_max' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) )
elseif rule['type'] == 'value' then
table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'value_min' then
table.insert( newClaims, p.filterUtter( claims, true ) )
elseif rule['type'] == 'value_max' then
table.insert( newClaims, p.filterUtter( claims, false ) )
end
end
claims = {}
--[[
Merge all claims
TODO: It's not good
]]
for j, newSubClaims in ipairs( newClaims ) do
for k, newClaim in ipairs( newSubClaims ) do
local isNew = true
for l, oldClaim in ipairs( claims ) do
if oldClaim['id'] == newClaim['id'] then
isNew = false
break
end
end
if isNew then
table.insert( claims, newClaim )
end
end
end
end
return claims
end
--[[
Filter statements by rank
Input: claims table, rank value, inversion
Output: filtered statements table
]]
function p.filterByRank( claims, rank, inversed )
if not inversed then
inversed = false
end
if not rank then
rank = 'best'
end
-- Check if rank value is valid
local isValidRank = false
for i, validRank in ipairs( validRanks ) do
if rank == validRank then
isValidRank = true
break
end
end
if not isValidRank then
throwError( 'rank-not-valid' )
end
-- Find the best rank
if rank == 'best' then
rank = 'normal' -- default rank (don't use deprecated even if it's no more claims)
-- If we have at least one preferred rank, mark it as best
for i, statement in pairs( claims ) do
if (statement.rank == 'preferred') then
rank = 'preferred'
break
end
end
end
local resultClaims = {};
for i, statement in pairs( claims ) do
if ( statement.rank == rank ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by language of value
Input: claims table, language, inversion
Output: filtered statements table
]]
function p.filterByLanguage( claims, language, inversed )
if not inversed then
inversed = false
end
local resultClaims = {}
local mulStatement = {}
for i, statement in ipairs( claims ) do
isMatchLanguage = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['language'] then
if statement['mainsnak']['datavalue']['value']['language'] == language then
isMatchLanguage = true
end
if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then
mulStatement = statement
end
end
if isMatchLanguage ~= inversed then
table.insert( resultClaims, statement )
end
end
if next(resultClaims) == nil and next(mulStatement) ~= nil then
-- if specific language is not found, but there is Q20923490 value
table.insert( resultClaims, mulStatement )
end
return resultClaims
end
--[[
Filter statements by unit of value
Input: claims table, unit, inversion
Output: filtered statements table
]]
function p.filterByUnit( claims, unit, inversed )
if not inversed then
inversed = false
end
unit = 'http://www.wikidata.org/entity/' .. string.upper( unit )
local resultClaims = {}
for i, statement in ipairs( claims ) do
isMatchUnit = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['unit']
and statement['mainsnak']['datavalue']['value']['unit'] == unit then
isMatchUnit = true
end
if isMatchUnit ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by position
Input: claims table, position, inversion
Output: filtered statements table
]]
function p.filterByPosition( claims, position, inversed )
if not inversed then
inversed = false
end
local resultClaims = {};
for statementPosition, statement in ipairs( claims ) do
if ( statementPosition == tonumber( position ) ) ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by qualifier existance or it's value
Input: claims table, ID of qualifier's property, qualifier's value, inversion
Output: filtered statements table
]]
function p.filterByQualifier( claims, qualifierId, value, inversed )
if not inversed then
inversed = false
end
qualifierId = string.upper( qualifierId )
local resultClaims = {}
for i, statement in ipairs( claims ) do
if statement['qualifiers'] and statement['qualifiers'][qualifierId] then
if value == nil then
if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then
table.insert( resultClaims, statement )
end
else
local isQualifierFound = false
for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
value = string.upper( value )
end
if qualifierValue == value then
isQualifierFound = true
break
end
end
end
if isQualifierFound ~= inversed then
table.insert( resultClaims, statement )
end
end
elseif inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by it's values
Input: claims table, value, inversed
Output: filtered statements table
]]
function p.filterByValue( claims, value, inversed )
inversed = inversed or false
local resultClaims = {}
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
value = string.upper( value )
end
end
if ( statementValue == value ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Find a statement with minimum or maximum value
Input: claims table, asc, inversed
Output: filtered statements table
]]
function p.filterUtter( claims, asc, inversed )
local resultValue = nil
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak'] and
statement['mainsnak']['datavalue'] and
statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
end
if not resultValue or ( statementValue < resultValue ) == asc then
resultValue = statementValue
end
end
end
mw.logObject( resultValue, 'resultValue' )
return p.filterByValue( claims, resultValue, inversed )
end
--[[
Find a statement with minimum or maximum qualifier value
Input: claims table, qualifierId, asc
Output: filtered statements table
]]
function p.filterUtterByQualifier( claims, qualifierId, asc )
qualifierId = string.upper( qualifierId )
local resultValue = nil
local resultStatement = nil
for i, statement in ipairs( claims ) do
if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then
if resultStatement == nil then
resultStatement = statement
end
else
for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'quantity' then
qualifierValue = qualifierValue.amount
end
if qualifier['datavalue']['type'] == 'time' then
qualifierValue = qualifierValue.time
end
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
end
if not resultValue or ( qualifierValue < resultValue ) == asc then
resultStatement = statement
resultValue = qualifierValue
end
end
end
end
end
return { resultStatement }
end
return p
0bdff3a63bf171160cdec5c966211fbbf3003880
Модуль:Wikidata/config
828
85
181
180
2025-01-31T15:24:24Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
-- Property configuration for Wikidata module
return {
global = {
separator = ', ',
conjunction = ' и ',
},
presets = {
['catonly'] = {
datatype = 'wikibase-item',
conjunction = '',
invisible = true,
['value-module'] = 'Wikidata/item',
['value-function'] = 'formatCategoryOnly',
references = '',
category = 'P910',
},
['country'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatCountryClaimWithFlag',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['from-to'] = {
datatype = 'time',
['property-module'] = 'Wikidata/date',
['property-function'] = 'formatDateIntervalProperty',
},
['link'] = {
['value-module'] = 'Wikidata/link',
['value-function'] = 'fromModule',
},
['list'] = {
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['name'] = {
datatype = 'monolingualtext',
monolingualLangTemplate = 'lang',
separator = '<br>',
conjunction = '<br>',
},
['place'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatPlaceWithQualifiers',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['quantity (date)'] = {
datatype = 'quantity',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
qualifier = 'P585',
},
},
datatypes = {
commonsMedia = {
limit = 1,
references = false,
size = '274x400px',
separator = '<br>',
conjunction = '<br>',
somevalue = '',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsMediaValue',
},
['external-id'] = {
references = false,
},
['globe-coordinate'] = {
limit = 1,
references = false,
},
url = {
separator = '<br>',
conjunction = '<br>',
references = false,
['value-module'] = 'Wikidata/url',
['value-function'] = 'formatUrlValue',
},
quantity = {
siConversion = true
}
},
properties = {
P6 = { datatype = 'wikibase-item', },
P17 = {
preset = 'country',
},
P18 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P19 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P20 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P22 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P25 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P26 = { datatype = 'wikibase-item', },
P27 = {
preset = 'country',
},
P31 = {
datatype = 'wikibase-item',
references = false,
},
P37 = { datatype = 'wikibase-item', },
P39 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/positions',
['claim-function'] = 'formatPositionClaim',
separator = '',
conjunction = '',
allowTables = true,
},
P40 = { datatype = 'wikibase-item', },
P41 = {
datatype = 'commonsMedia',
size = '150x200px',
},
P53 = {
datatype = 'wikibase-item',
category = 'P910',
},
P54 = {
category = 'P6112',
},
P57 = {
datatype = 'wikibase-item',
preset = 'list',
},
P58 = {
datatype = 'wikibase-item',
preset = 'list',
},
P59 = {
datatype = 'wikibase-item',
category = 'P910',
references = false,
},
P69 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P3876',
qualifier = 'P582',
},
P94 = {
datatype = 'commonsMedia',
size = '100x200px',
},
P86 = {
datatype = 'wikibase-item',
preset = 'list',
},
P101 = { datatype = 'wikibase-item', },
P102 = {
datatype = 'wikibase-item',
preset = 'list',
qualifier = 'P582',
category = 'P6365',
},
P103 = { datatype = 'wikibase-item', },
P106 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
},
P108 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P4195',
},
P109 = {
datatype = 'commonsMedia',
size = '150x150px',
alt = 'Изображение автографа',
},
P117 = {
datatype = 'commonsMedia',
size = '290x300px',
alt = 'Изображение химической структуры',
},
P119 = {
preset = 'place',
thisLocationOnly = 'true',
},
P131 = { datatype = 'wikibase-item', },
P140 = {
datatype = 'wikibase-item',
},
P154 = {
size = '220x80px',
alt = 'Изображение логотипа',
},
P159 = {
preset = 'place',
},
P161 = {
preset = 'list',
},
P162 = {
preset = 'list',
},
P163 = { datatype = 'wikibase-item', },
P166 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/Medals',
['property-function'] = 'formatProperty',
['value-module'] = 'Wikidata/Medals',
['value-function'] = 'formatValue',
before = '<div style="text-align:justify">',
after = '</div>',
separator = ' ',
conjunction = ' ',
references = false,
allowTables = true,
},
P190 = { datatype = 'wikibase-item', },
P212 = {
preset = 'link',
},
P225 = {
preset = 'list',
['claim-module'] = 'Wikidata/Biology',
['claim-function'] = 'formatTaxonNameClaim',
},
P237 = { datatype = 'wikibase-item', },
P241 = { datatype = 'wikibase-item', },
P242 = {
datatype = 'commonsMedia',
size = '300x300px',
},
P247 = {
formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1',
},
P267 = {
preset = 'link',
},
P276 = {
preset = 'place',
},
P281 = { datatype = 'string', },
P286 = {
preset = 'list',
},
P296 = {
formatter = 'http://osm.sbin.ru/esr/esr:$1',
},
P301 = {
rawArticle = true,
},
P344 = {
preset = 'list',
},
P345 = {
preset = 'link',
},
P348 = {
preset = 'list',
['property-module'] = 'Wikidata/Software',
['property-function'] = 'formatVersionProperty',
},
P361 = { datatype = 'wikibase-item', },
P373 = {
datatype = 'string',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsCategory',
limit = 1,
references = false,
},
P374 = { datatype = 'external-id', },
P395 = { datatype = 'string', },
P407 = { datatype = 'wikibase-item', },
P410 = { datatype = 'wikibase-item', },
P412 = {
datatype = 'wikibase-item',
category = 'P910',
},
P413 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
category = 'P910',
},
P414 = {
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'applyDefaultTemplate',
},
P421 = { datatype = 'wikibase-item', },
P473 = { datatype = 'string', },
P495 = {
preset = 'country',
},
P505 = {
preset = 'list',
},
P512 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/P512',
['property-function'] = 'formatAcademicDegree',
},
P527 = {
preset = 'list',
},
P528 = {
references = false,
qualifier = 'P972',
},
P551 = {
preset = 'place',
},
P569 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfBirthClaim',
},
P570 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfDeathClaim',
},
P571 = { datatype = 'time', },
P576 = { datatype = 'time', },
P598 = { datatype = 'wikibase-item', },
P607 = {
datatype = 'wikibase-item',
preset = 'list',
},
P625 = { datatype = 'globe-coordinate', },
P669 = {
qualifier = 'P670',
},
P685 = {
formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1',
},
P721 = {
preset = 'link',
},
P764 = {
preset = 'link',
},
P803 = { datatype = 'wikibase-item', },
P856 = { datatype = 'url', },
P881 = {
novalue = 'нет',
category = 'P910',
},
P884 = {
preset = 'link',
},
P915 = {
category = 'P1740',
},
P957 = {
preset = 'link',
},
P972 = {
preset = 'catonly',
},
P1077 = {
preset = 'link',
},
P1082 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1098 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1120 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1128 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1114 = {
datatype = 'quantity',
qualifier = 'P585',
},
P1174 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1195 = {
['value-module'] = 'Wikidata/Software',
['value-function'] = 'formatExtension',
conjunction = ' или ',
},
P1215 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatVisualMagnitude'
},
P1246 = {
preset = 'link',
},
P1249 = { datatype = 'time', },
P1352 = { preset = 'quantity (date)', },
P1376 = { datatype = 'wikibase-item', },
P1402 = {
preset = 'link',
},
P1448 = {
preset = 'name',
},
P1458 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatColorIndex'
},
P1464 = { datatype = 'wikibase-item', },
P1476 = {
preset = 'name',
},
P1477 = {
preset = 'name',
},
P1532 = {
preset = 'country',
rank = '[rank:normal, rank:preferred]',
},
P1543 = {
datatype = 'commonsMedia',
},
P1559 = {
preset = 'name',
},
P1603 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1621 = {
size = '300x300px',
},
P1692 = {
preset = 'link',
},
P1705 = {
preset = 'name',
},
P1753 = {
rowArticle = true,
},
P1809 = {
preset = 'list',
},
P1846 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P2031 = {
preset = 'from-to',
to = 'P2032',
within = 'P570',
},
P2043 = {
preset = 'quantity (date)',
},
P2044 = { datatype = 'quantity', },
P2046 = {
preset = 'quantity (date)',
siConversion = false,
},
P2047 = {
siConversion = false,
},
P2048 = {
conjunction = ' или ',
},
P2060 = {
siConversion = false,
},
P2097 = {
siConversion = false,
},
P2120 = {
siConversion = false,
},
P2137 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2139 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2146 = {
siConversion = false,
},
P2214 = {
siConversion = false
},
P2226 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2257 = {
siConversion = false
},
P2260 = {
siConversion = false
},
P2295 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2324 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.'
},
P2403 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2425 = {
alt = 'Изображение орденской планки',
},
P2583 = {
siConversion = false,
},
P2597 = {
preset = 'catonly',
},
P2650 = { datatype = 'wikibase-item', },
P2789 = {
preset = 'list',
},
P2896 = {
siConversion = false,
},
P2910 = {
size = '100x80px',
},
P3083 = {
formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1',
},
P3086 = {
siConversion = false,
},
P3362 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P4614 = {
category = 'P1200',
},
P5348 = {
siConversion = false,
},
P6257 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatRA',
},
P6258 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatDMS',
},
P6259 = {
['references'] = false,
},
P7584 = {
siConversion = false,
},
P8010 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P8224 = {
alt = 'Изображение молекулярной модели',
},
},
categories = {
['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи',
['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные',
['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи',
['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных',
['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки',
['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке',
['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке',
},
errors = {
['property-param-not-provided'] = 'Не дан параметр свойства',
['entity-not-found'] = 'Сущность не найдена.',
['unknown-claim-type'] = 'Неизвестный тип заявления.',
['unknown-snak-type'] = 'Неизвестный тип снэка.',
['unknown-datavalue-type'] = 'Неизвестный тип значения данных.',
['unknown-entity-type'] = 'Неизвестный тип сущности.',
['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.',
['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.',
['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.',
['property-module-not-found'] = 'Модуль для отображения свойства не найден',
['property-function-not-found'] = 'Функция для отображения свойства не найдена',
['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.',
['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.',
['value-module-not-found'] = 'Модуль для отображения значения не найден.',
['value-function-not-found'] = 'Функция для отображения значения не найдена.',
},
i18n = {
somevalue = "''неизвестно''",
novalue = '',
-- Обстоятельства источника
Q5727902 = 'около ',
Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ',
Q30230067 = 'возможно ',
Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем"><</span> ',
Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">></span> ',
Q60070514 = 'примерно ',
thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'},
},
deprecatedSources = {
Q355 = true, -- Facebook
Q36578 = true, -- Gemeinsame Normdatei
Q63056 = true, -- Find a Grave
Q212256 = true, -- АиФ
Q504063 = true, -- Discogs
Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748
Q1798125 = true, -- LIBRIS
Q2621214 = true, -- Geni
Q15222191 = true, -- BNF
Q15241312 = true, -- Freebase
Q19938912 = true, -- BNF
Q21697707 = true, -- Хайазг
Q25328680 = true, -- Prabook
Q29861311 = true, -- SNAC
Q86999151 = true, -- WeChangEd
},
};
bd6091486f675bebf109cb52de53a162b05a5243
Шаблон:Nobr
10
86
183
182
2025-01-31T15:24:24Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! -->
</noinclude>
989c6f164ed3a8543e916c8f1746ba1ab94fb068
Шаблон:If-wikidata
10
87
185
184
2025-01-31T15:24:25Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude>
{{doc}}
</noinclude>
a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb
Модуль:Wikidata/media
828
88
187
186
2025-01-31T15:24:25Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
-- Константы
local contentLanguageCode = mw.getContentLanguage():getCode();
function p.formatCommonsCategory( context, options, value )
local link = 'commons:Category:' .. value
local title = value .. ' на Викискладе'
if ( options['text'] and options['text'] ~= '' ) then
title = options['text']
end
commons = '[[' .. link .. '|' .. title .. ']]'
--Commons icon
if ( not options['icon'] or options['icon'] ~= '-' ) then
local icon_size = '15px'
if ( options['icon_size'] and options['icon_size'] ~= '' ) then
icon_size = options['icon_size']
end
commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons
end
--Text before and after link
if ( options['text_before'] and options['text_before'] ~= '' ) then
if ( options['text_before'] ~= '-' ) then
commons = options['text_before'] .. ' ' .. commons
end
end
if ( options['text_after'] and options['text_after'] ~= '' ) then
if ( options['text_after'] ~= '-' ) then
commons = commons .. ' ' .. options['text_after']
end
end
return commons
end
--[[
Временный хак, нужно добавить config, getConfig и getCategoryByCode
в options, чтобы они были доступны в любом месте кода.
]]
local config;
local function getCategoryByCode( code, sortkey )
if config == nil then
config = require( 'Module:Wikidata/config' );
end;
local value = config[ 'categories' ][ code ];
if not value or value == '' then
return '';
end
return '[[Category:' .. value .. ']]';
end
local function getCaption( context, options )
local caption = ''
if options.qualifiers and options.qualifiers.P2096 then
for i, qualifier in pairs( options.qualifiers.P2096 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'monolingualtext'
and qualifier.datavalue.value
and qualifier.datavalue.value.language == contentLanguageCode ) then
caption = qualifier.datavalue.value.text
break
end
end
end
if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then
local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue )
if not caption or caption == '' then
caption = moment
else
caption = caption .. ', ' .. moment
end
end
local localValue = '';
if options[ 'value' ] and options[ 'value' ] ~= '' then
localValue = options[ 'value' ];
end
local localCaption = '';
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
localCaption = options[ 'caption' ];
end
if localValue ~= '' then
caption = localCaption;
end
local formattedCaption = ''
if caption ~= '' then
formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } );
end
if localValue == '' and localCaption ~= '' then
formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' )
if options.frame:preprocess('{{REVISIONID}}') == '' then
formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>'
end
end
return caption, formattedCaption
end
function p.formatCommonsMediaValue( context, options, value )
local image = value;
local caption, formattedCaption = getCaption( context, options )
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]]
image = '[[File:' .. value .. '|frameless';
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border';
end
local size = options[ 'size' ];
if size and size ~= '' then
if not string.match( size, 'px$' )
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
then
size = size .. 'px'
end
-- временно
if string.match( size, 'pxpx' ) then
image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image
end
else
size = fileDefaultSize;
end
image = image .. '|' .. size;
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ];
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]';
if formattedCaption ~= '' then
image = image .. '<br>' .. formattedCaption;
end
else
image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' );
end
if options.entity and options.fixdouble then
local page = mw.title.getCurrentTitle()
local txt = page:getContent()
if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then
if options.frame:preprocess('{{REVISIONID}}') == '' then
image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>'
end
image = image .. getCategoryByCode( 'media-contains-local-double' )
end
end
return image
end
return p
ec384e72491465f4103cce95a8f9467df428a432
Шаблон:Карточка/оригинал названия
10
89
189
188
2025-01-31T15:24:25Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!--
-->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude>
4eccda042428e1113ff320ff5d6b760a7f52b088
Шаблон:Br separated entries
10
90
191
190
2025-01-31T15:24:26Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude>
{{doc}}
</noinclude>
2113c3c6e95a84235b9f7a85e7ea17208e8f91df
Шаблон:Карточка/блок с маркерами
10
91
193
192
2025-01-31T15:24:26Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude>
71e7755aa4fb1e445f008da13d6fa4212aea3c38
Шаблон:Карточка/блок
10
92
195
194
2025-01-31T15:24:26Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude>
b76f4bc95a8a44fea1fa0f577d84111b51ce1385
Модуль:Infobox/bulleted block
828
93
197
196
2025-01-31T15:24:26Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
-- takes strings or nils; returns a string
function makeText(frame, text, wikidata, from)
if wikidata and wikidata ~= ''then
return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}}
else
return text or ''
end
end
-- from [[ru:Модуль:Infobox]]
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.main(frame)
local args = frame:getParent().args
local maxNumberArgs = maxNumber(args)
local texts = {}
for i = 1, maxNumberArgs do
if args['текст' .. i] then
texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from'])
end
end
local textsAreEmpty = true
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
textsAreEmpty = false
end
end
local results = {}
if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then
results['текст1'] = args['подзаголовок']
results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;'
end
local mainText = makeText(frame, args['текст'], args['викиданные'], args['from'])
if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then
mainText = ' '
end
if mainText and mainText ~= '' then
results['метка2'] = args['метка']
results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;'
results['текст2'] = mainText
results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;'
end
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
results['метка' .. (i+2)] = ' • ' .. (args['метка' .. i] or '')
results['текст' .. (i+2)] = texts[i]
local last = true
for j = i+1, maxNumberArgs do
if texts[j] and texts[j] ~= '' then
last = false
end
end
if last then
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;'
else
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
end
end
end
return frame:expandTemplate{title='Карточка/блок', args=results}
end
return p
856b97606e1f2809c940e384f6fe71a575ca019e
Шаблон:Число
10
94
199
198
2025-01-31T15:24:27Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1= {{{2|}}}}} }} }}<noinclude>
{{doc}}
</noinclude>
acfc1e9cec817e6742b18106f020ac388ececc7e
Модуль:Wikidata/count
828
95
201
200
2025-01-31T15:24:27Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
function p.getCount( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims;
if options.property then -- TODO: Почему тут может не быть property?
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return ''; --TODO error?
end
return table.getn(claims);
end
function p.isMultiple( context, options )
local count = p.getCount( context, options );
local multiple = '';
if( count ~= nil and count ~= '' and count > 1 ) then
multiple = 1;
end
return multiple;
end
return p
8ccf5dd7170a466674627b0afdf32c6bd2318154
Шаблон:Без начала
10
96
203
202
2025-01-31T15:24:28Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude>
9fbca6f1fc236cb17fe77d76891e3f9c2afa2117
Шаблон:Карточка/официальное название
10
97
205
204
2025-01-31T15:24:28Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude>
708a700c58a199343531d8fb3eec7ee897e92732
Шаблон:Карточка/флаг и герб
10
98
207
206
2025-01-31T15:24:29Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<templatestyles src="Шаблон:Карточка/styles.css" /><table role="presentation" class="ts-infobox-flaginfo">
<tr>
{{if-wikidata|p41|{{{флаг|}}}|<td>{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|<td>{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}}
</tr>
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr>
{{if-wikidata|p41|{{{флаг|}}}|3=<td class="media-caption">{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|3=<td class="media-caption">{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}}
</tr>}}</table>
}}<noinclude>
{{doc}}
</noinclude>
1790949866597b0909572cd51fdfb8b9a7db55ff
Шаблон:Lang-sv
10
99
209
208
2025-01-31T15:24:29Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
[[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
c4b5e81c6405972dcea4cc26ab77e99e9bd2021f
Шаблон:Население государства
10
100
211
210
2025-01-31T15:24:29Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1}}}
| Республика Южная Осетия = Население Южной Осетии{{!}}Население
| Население
}}</includeonly><noinclude>
{{doc}}
[[Категория:Шаблоны по странам]]
</noinclude>
e0568280ef5056e94f5f1abf1934f4188a52c35f
Шаблон:Lang-fi
10
101
213
212
2025-01-31T15:24:30Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
[[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
16ac91b8e1e294e7687d57c0757c178f9662581c
Шаблон:Demo
10
102
215
214
2025-01-31T15:24:30Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude>
e458e378477c6077a01987f334fdc73bee48512c
Модуль:Demo
828
103
217
216
2025-01-31T15:24:30Z
Генерал Альдации
2
1 версия импортирована
Scribunto
text/plain
local p = {}
local getArgs = require('Модуль:Arguments').getArgs
local function hasValue(param)
if param and param:find('%S') then
return true
end
end
--creates a frame object that cannot access any of the parent's args
--unless a table containing a list keys of not to inherit is provided
function disinherit(frame, onlyTheseKeys)
local parent = frame:getParent() or frame
local orphan = parent:newChild{}
orphan.getParent = parent.getParent --returns nil
orphan.args = {}
if onlyTheseKeys then
local family = {parent, frame}
for f = 1, 2 do
for k, v in pairs(family[f] and family[f].args or {}) do
orphan.args[k] = orphan.args[k] or v
end
end
parent.args = mw.clone(orphan.args)
setmetatable(orphan.args, nil)
for _, k in ipairs(onlyTheseKeys) do
rawset(orphan.args, k, nil)
end
end
return orphan, parent
end
function p.get(frame, arg, passArgs)
local orphan, frame = disinherit(frame, passArgs and {arg or 1})
local code, noWiki, preserve = frame.args[arg or 1] or ''
local kill_categories = not frame.args.save_categories
local tag, sep
if code:match'nowiki' then
local placeholder, preserve = ('6'):char(), {}
-- We replace "}%-" and "%-{" because of some server bug probably connected to
-- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to
-- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>'))
-- outputting '}-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>"
code = mw.text.unstripNoWiki(code)
:gsub('<', '<')
:gsub('>', '>')
:gsub('}%-', '}-')
:gsub('%-{', '-{')
if (mw.text.trim(code):match'\n') then
tag = 'pre'
sep = ''
end
noWiki = code:gsub('%%', placeholder)
for k in noWiki:gmatch('&.-;') do
table.insert(preserve, (k:gsub('&', '&')))
noWiki = noWiki:gsub('(&.-;)', '%%%s')
end
noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%')
end
return {
source = noWiki or code,
output = orphan:preprocess(code)
:gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[К:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame,
args = getArgs(frame),
tag = tag,
sep = sep
}
end
function p.main(frame, demoTable)
local show = demoTable or p.get(frame)
local args = show.args
local yesno = require('Module:Yesno')
args.reverse = yesno(args.reverse, false)
args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code"
args.sep = args.sep or args.br or show.sep
args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ')
if show[args.result_arg] then
return show[args.result_arg]
end
return args.reverse
and string.format(
'%s%s<%s%s%s>%s</%s>',
show.output,
args.sep,
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag
)
or string.format(
'<%s%s%s>%s</%s>%s%s',
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag,
args.sep,
show.output
)
end
--passing of args into other module without preprocessing
function p.module(frame)
local orphan, frame = disinherit(frame, {
'demo_template',
'demo_module',
'demo_module_func',
'demo_main',
'demo_br',
'demo_result_arg',
'demo_save_categories'
})
local template = frame.args.demo_template and 'Template:'..frame.args.demo_template
local demoFunc = frame.args.demo_module_func or 'main\n'
local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')]
frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg
local kill_categories = not save_categories
if demoModule then
local named = {insert = function(self, ...) table.insert(self, ...) return self end}
local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'}
if not template then
source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc)
end
local insertNamed = #source + 1
for k, v in pairs(orphan.args) do
local nan, insert = type(k) ~= 'number', {v}
local target = nan and named or source
target:insert'|'
if nan then
target:insert(k):insert'=':insert'\n'
table.insert(insert, 1, #target)
end
target:insert(unpack(insert))
local nowiki = v:match('nowiki')
if nowiki or v:match('{{.-}}') then
orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v)
end
end
source:insert'}}'
table.insert(source, insertNamed, table.concat(named))
return p.main(orphan, {
source = mw.text.encode(table.concat(source), "<>'|=~"),
output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame
})
else
return "ERROR: Invalid module function: "..demoFunc
end
end
return p
9beaf8f8041a39ae73ba17b2f70609171c4196d3
Шаблон:Государство/doc
10
104
219
218
2025-01-31T15:24:30Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах;
* для исторических государств используйте {{t|историческое государство}}.
* для составных частей государств используйте {{t|Административная единица}}.
== Образец для копирования ==
<pre>
{{Государство
|Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять -->
|Русское название =
|Оригинальное название =
|Родительный падеж =
|Герб =
|Вместо герба =
|Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва -->
|Перевод девиза =
|Название гимна =
|Перевод названия гимна =
|Аудио =
|Форма правления =
|Государственный строй =
|Государственная религия =
|На карте =
|подпись к карте =
|На карте2 =
|Язык/Языки =
|Основано/Основана =
|Дата/Даты независимости =
|Независимость от =
|Столица =
|Крупнейшие города =
|Должность руководителя 1 =
|Руководитель 1 =
|Должность руководителя 2 =
|Руководитель 2 =
|Должность руководителя 3 =
|Руководитель 3 =
|Должность руководителя 4 =
|Руководитель 4 =
|Должность руководителя 5 =
|Руководитель 5 =
|Место по территории =
|Территория =
|Процент воды =
|Этнохороним =
|Место по населению =
|Население =
|Год оценки =
|Население по переписи =
|Год переписи =
|Плотность населения =
|Место по плотности =
|ВВП (ППС) =
|Год расчёта ВВП (ППС) =
|Место по ВВП (ППС) =
|ВВП (ППС) на душу населения =
|Место по ВВП (ППС) на душу населения =
|ВВП (номинал) =
|Год расчёта ВВП (номинал) =
|Место по ВВП (номинал) =
|ВВП (номинал) на душу населения =
|Место по ВВП (номинал) на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта =
|Домен/Домены =
|Телефонный код =
|Часовой пояс =
|Автомобильное движение =
|Примечания =
<!-- |Без флага и герба=* -->
<!-- |Без гимна=* -->
}}
</pre>
== Описание параметров ==
Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]] —
<pre> |Язык = [[Албанский язык|албанский]]</pre>
а в статье [[Канада]] —
<pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre>
Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»:
<pre>
|Спорный статус = да
|Основано =
|Основана =
|Дата образования =
|Провозглашение независимости =
|Дипломатическое признание =
|Независимость от =
</pre>
Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус = непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]].
== Пример использования ==
{{demo|reverse=1|br=|<nowiki>{{Государство
|Русское название = Финляндская Республика
|Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}}
|Родительный падеж = Финляндии
|Герб = Coat of arms of Finland.svg
|Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} -->
|Вместо герба =
|Девиз =
|Перевод девиза =
|Название гимна = Maamme
|Перевод названия гимна = Наш край
|Аудио =
|Форма правления = [[президентская республика]]
|Государственный строй = [[унитарное государство]]
|Государственная религия =
|На карте = EU-Finland.svg
|подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный)
|На карте2 =
|Языки = [[финский язык|финский]], [[шведский язык|шведский]]
|Основано/Основана =
|Дата независимости = [[6 декабря]] [[1917]]
|Независимость от = [[Россия|России]]
|Столица = [[Хельсинки]]
|Крупнейший город = Хельсинки
|Должность руководителя 1 = [[Президент Финляндии|Президент]]
|Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]]
|Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]]
|Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]]
|Место по территории = 63
|Территория = 338 145
|Процент воды = 9,96
|Этнохороним = финляндец, финляндка
|Место по населению = 106
|Население = 5 219 732
|Год оценки = 2003
|Население по переписи =
|Год переписи =
|Плотность населения = 15,4
|Место по плотности =
|ВВП =
|Год расчёта ВВП =
|Место по ВВП =
|ВВП на душу населения =
|Место по ВВП на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref>
|Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]])
|Телефонный код = 358
|Часовой пояс = +2
|Автомобильное движение =
|Примечания = <references/>
}}</nowiki>}}
== TemplateData ==
<templatedata>
{
"params": {
"Спорный статус": {},
"Статус": {},
"Русское название": {},
"Оригинальное название": {},
"Флаг": {
"type": "wiki-file-name"
},
"Ссылка на флаг": {},
"Родительный падеж": {},
"Герб": {
"type": "wiki-file-name"
},
"Отображаемая подпись герба": {},
"Вместо герба": {},
"Девиз": {},
"Перевод девиза": {},
"Без гимна": {},
"Название гимна": {},
"Перевод названия гимна": {},
"Аудио": {},
"На карте": {},
"На карте2": {},
"Дата1": {},
"Дата2": {},
"Дата3": {},
"Дата4": {},
"Дата5": {},
"Дата6": {},
"Дата7": {},
"Дата8": {},
"Дата9": {},
"Дата10": {},
"Дата11": {},
"Дата12": {},
"sovereignty_type": {},
"Этап1": {},
"Этап2": {},
"Этап3": {},
"Этап4": {},
"Этап5": {},
"Этап6": {},
"Этап7": {},
"Этап8": {},
"Этап9": {},
"Этап10": {},
"Этап11": {},
"Этап12": {},
"Основана": {},
"Основано": {},
"Дата образования": {},
"Провозглашение независимости": {},
"Независимость от": {},
"Дипломатическое признание": {},
"Отображаемый тип независимости": {},
"Даты независимости": {},
"Дата независимости": {},
"Язык": {},
"Языки": {},
"Столица": {},
"Крупнейший город": {},
"Крупнейшие города": {},
"Форма правления": {},
"Должность руководителя 1": {},
"Должности руководителей": {},
"Руководитель 1": {},
"Руководители": {},
"Должность руководителя 2": {},
"Руководитель 2": {},
"Должность руководителя 3": {},
"Руководитель 3": {},
"Должность руководителя 4": {},
"Руководитель 4": {},
"Должность руководителя 5": {},
"Руководитель 5": {},
"Государственная религия": {},
"Место по территории": {},
"Территория": {},
"Процент воды": {},
"Территория2": {},
"Население": {},
"Год оценки": {},
"Год переписи": {},
"Население2": {},
"Место по населению": {},
"Население по переписи": {},
"Плотность населения": {},
"Место по плотности": {},
"ВВП": {},
"Год расчёта ВВП": {},
"Место по ВВП": {},
"ВВП на душу населения": {},
"Место по ВВП на душу населения": {},
"ВВП (ППС)": {},
"Год расчёта ВВП (ППС)": {},
"Место по ВВП (ППС)": {},
"ВВП (ППС) на душу населения": {},
"Место по ВВП (ППС) на душу населения": {},
"ВВП (номинал)": {},
"Год расчёта ВВП (номинал)": {},
"Место по ВВП (номинал)": {},
"ВВП (номинал) на душу населения": {},
"Место по ВВП (номинал) на душу населения": {},
"Год расчёта ИРЧП": {},
"ИРЧП": {},
"Уровень ИРЧП": {},
"Место по ИРЧП": {},
"Этнохороним": {},
"Валюта": {},
"Домены": {},
"Домен": {},
"Телефонный код": {},
"Часовые пояса": {},
"Часовой пояс": {},
"Примечания": {},
"nocat": {
"type": "boolean"
},
"lat_deg": {},
"lat_min": {},
"lat_sec": {},
"lat_dir": {},
"lon_deg": {},
"lon_min": {},
"lon_sec": {},
"lon_dir": {},
"region": {},
"CoordScale": {},
"Размер герба": {
"aliases": [
"размер герба"
],
"type": "number"
},
"Размер флага": {
"aliases": [
"размер флага"
],
"type": "number"
},
"Размер карты": {
"aliases": [
"размер карты"
]
},
"Подпись к карте": {
"aliases": [
"подпись к карте"
]
},
"Размер карты2": {
"aliases": [
"размер карты2"
]
},
"Государственный строй": {},
"Автомобильное движение": {}
},
"paramOrder": [
"Статус",
"Спорный статус",
"Русское название",
"Оригинальное название",
"Флаг",
"Размер флага",
"Ссылка на флаг",
"Родительный падеж",
"Герб",
"Размер герба",
"Отображаемая подпись герба",
"Вместо герба",
"Девиз",
"Перевод девиза",
"Без гимна",
"Название гимна",
"Перевод названия гимна",
"Аудио",
"На карте",
"Размер карты",
"Подпись к карте",
"На карте2",
"Размер карты2",
"Дата1",
"Дата2",
"Дата3",
"Дата4",
"Дата5",
"Дата6",
"Дата7",
"Дата8",
"Дата9",
"Дата10",
"Дата11",
"Дата12",
"sovereignty_type",
"Этап1",
"Этап2",
"Этап3",
"Этап4",
"Этап5",
"Этап6",
"Этап7",
"Этап8",
"Этап9",
"Этап10",
"Этап11",
"Этап12",
"Основана",
"Основано",
"Дата образования",
"Провозглашение независимости",
"Независимость от",
"Дипломатическое признание",
"Отображаемый тип независимости",
"Даты независимости",
"Дата независимости",
"Язык",
"Языки",
"Столица",
"Крупнейший город",
"Крупнейшие города",
"Форма правления",
"Государственный строй",
"Должность руководителя 1",
"Должности руководителей",
"Руководитель 1",
"Руководители",
"Должность руководителя 2",
"Руководитель 2",
"Должность руководителя 3",
"Руководитель 3",
"Должность руководителя 4",
"Руководитель 4",
"Должность руководителя 5",
"Руководитель 5",
"Государственная религия",
"Место по территории",
"Территория",
"Процент воды",
"Территория2",
"Население",
"Год оценки",
"Год переписи",
"Население2",
"Место по населению",
"Население по переписи",
"Плотность населения",
"Место по плотности",
"ВВП",
"Год расчёта ВВП",
"Место по ВВП",
"ВВП на душу населения",
"Место по ВВП на душу населения",
"ВВП (ППС)",
"Год расчёта ВВП (ППС)",
"Место по ВВП (ППС)",
"ВВП (ППС) на душу населения",
"Место по ВВП (ППС) на душу населения",
"ВВП (номинал)",
"Год расчёта ВВП (номинал)",
"Место по ВВП (номинал)",
"ВВП (номинал) на душу населения",
"Место по ВВП (номинал) на душу населения",
"Год расчёта ИРЧП",
"ИРЧП",
"Уровень ИРЧП",
"Место по ИРЧП",
"Этнохороним",
"Валюта",
"Домены",
"Домен",
"Телефонный код",
"Часовые пояса",
"Часовой пояс",
"Автомобильное движение",
"Примечания",
"lat_deg",
"lat_min",
"lat_sec",
"lat_dir",
"lon_deg",
"lon_min",
"lon_sec",
"lon_dir",
"region",
"CoordScale",
"nocat"
],
"format": "block"
}
</templatedata>
== См. также ==
* {{tl|Историческое государство}}
<includeonly>
[[Категория:Шаблоны-карточки:Географические объекты]]
</includeonly>
b1e2b1107db0671d3bcc4dda5bd29020192c442e
Шаблон:Карточка/styles.css
10
105
221
220
2025-01-31T15:24:31Z
Генерал Альдации
2
1 версия импортирована
text
text/plain
/* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */
/* [[Шаблон:Карточка/флаг и герб]] */
.ts-infobox-flaginfo {
background: none;
border-collapse: collapse;
display: table;
text-align: center;
width: 100%;
}
.ts-infobox-flaginfo td {
vertical-align: middle;
}
body.skin--responsive.skin-minerva.skin-minerva .ts-infobox-flaginfo td {
/* Минерва требует хаков, чтобы эти стили работали */
border-bottom: 0;
vertical-align: middle;
}
/* Таблицы */
.infobox-table,
.infobox-tablebox {
padding: 0;
}
.infobox-inner-table,
.infobox-table > table,
.infobox-tablebox > table {
width: 100%;
display: table;
margin: 0;
background: transparent;
}
.infobox-tablebox > table {
border: 1px solid var(--border-color-base, #a2a9b1);
border-collapse: separate;
}
/* Встраиваемая карточка */
.infobox-child {
width: 100%;
margin: 0;
padding: 0;
border: none;
font-size: 100%;
}
body.skin-minerva table.infobox-child {
width: 100% !important;
margin: 0 !important;
padding: 0;
border: none;
font-size: 100%;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
25901ad6113ef3908fc70305ce64eb64925c665f
Шаблон:Государство
10
106
223
222
2025-01-31T15:25:29Z
Генерал Альдации
2
1 версия импортирована
wikitext
text/x-wiki
{{Карточка
|имя = Государство
|автозаголовки = да
|from = {{{from|}}}
|вверху0 = {{#switch: {{{Статус|}}}
| виртуальное = [[Виртуальное государство]]
| особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }}
| Непризнанное
| непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }}
| Частично признанное
| частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }}
}}
|вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}}
|вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}}
|изображение = {{Карточка/флаг и герб
| флаг = {{{Флаг|}}}
| флаг ширина = {{{Размер флага|}}}{{{размер флага|}}}
| флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]]
| герб = {{{Герб|}}}
| герб ширина = {{{Размер герба|}}}{{{размер герба|}}}
| герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }}
|from={{{from|}}}}}
|текст1 = {{br separated entries
| {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }}
| {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }}
}}
|текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }}
|текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }}
|заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }}
|стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left;
|блок5 =
{{Карточка/блок с маркерами
|метка1 = {{nobr|{{{Дата1}}}}}
|текст1 = {{{Этап1|}}}
|метка2 = {{nobr|{{{Дата2}}}}}
|текст2 = {{{Этап2|}}}
|метка3 = {{nobr|{{{Дата3}}}}}
|текст3 = {{{Этап3|}}}
|метка4 = {{nobr|{{{Дата4}}}}}
|текст4 = {{{Этап4|}}}
|метка5 = {{nobr|{{{Дата5}}}}}
|текст5 = {{{Этап5|}}}
|метка6 = {{nobr|{{{Дата6}}}}}
|текст6 = {{{Этап6|}}}
|метка7 = {{nobr|{{{Дата7}}}}}
|текст7 = {{{Этап7|}}}
|метка8 = {{nobr|{{{Дата8}}}}}
|текст8 = {{{Этап8|}}}
|метка9 = {{nobr|{{{Дата9}}}}}
|текст9 = {{{Этап9|}}}
|метка10 = {{nobr|{{{Дата10}}}}}
|текст10 = {{{Этап10|}}}
|метка11 = {{nobr|{{{Дата11}}}}}
|текст11 = {{{Этап11|}}}
|метка12 = {{nobr|{{{Дата12}}}}}
|текст12 = {{{Этап12|}}}
|from={{{from|}}}}}
|заголовок6 = -
|метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]]
|текст7 = {{{Основана|}}}{{{Основано|}}}
|викиданные7 =
<!-- СПОРНЫЙ СТАТУС -->
<!-- Спорный статус заполнен -->
|метка8 = [[Основание государства|Дата образования]]
|текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }}
|викиданные8 =
|метка9 = Провозглашение независимости
|текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные9 =
|метка10 = [[Международно-правовое признание|Дипломатическое признание]]
|текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }}
|викиданные10 =
<!-- Спорный статус не заполнен -->
|метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }}
|текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные11 =
<!-- / СПОРНЫЙ СТАТУС -->
|метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]]
|текст12 = {{{Язык|{{{Языки|}}}}}}
|викиданные12 = p37
|метка13 = [[Столица]]
|текст13 = {{{Столица|}}}
|викиданные13 = p36
|метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }}
|текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}}
|викиданные14 =
|метка15 = [[Форма государственного правления|Форма правления]]
|текст15 = {{{Форма правления|}}}
|викиданные15 =
|метка16 = [[Форма государственного устройства|Государственный строй]]
|текст16 = {{{Государственный строй|}}}
|метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}}
|текст17 = {{{Руководитель 1|{{{Руководители|}}}}}}
|метка18 = {{{Должность руководителя 2}}}
|текст18 = {{{Руководитель 2|}}}
|метка19 = {{{Должность руководителя 3}}}
|текст19 = {{{Руководитель 3|}}}
|метка20 = {{{Должность руководителя 4}}}
|текст20 = {{{Руководитель 4|}}}
|метка21 = {{{Должность руководителя 5}}}
|текст21 = {{{Руководитель 5|}}}
|метка22 = {{{Должность руководителя 6}}}
|текст22 = {{{Руководитель 6|}}}
|метка23 = [[Государственная религия|Гос. религия]]
|текст23 = {{{Государственная религия|}}}
|викиданные23 =
|блок24 =
{{Карточка/блок с маркерами
|подзаголовок = [[Территория государства|Территория]]
|метка1 = Всего
|текст1 = {{br separated entries
| {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | {{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }}
| {{число|{{{Территория2|}}}|км²}}
}}
|метка2 = % водной поверхности
|текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }}
|from={{{from|}}}}}
|блок25 =
{{Карточка/блок с маркерами
|подзаголовок = [[{{Население государства|{{PAGENAME}}}}]]
|метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }}
|текст1 = {{br separated entries
| {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | ([[Список стран по населению|{{{Место по населению}}}-е]]) }}
| {{число|{{{Население2|}}}|чел.}}
}}
|метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }}
|текст2 = {{число|{{{Население по переписи|}}}|чел.}}
|метка3 = [[Плотность населения|Плотность]]
|текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | ([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }}
|from={{{from|}}}}}
|блок26 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]]
|метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }}
|текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок27 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }}
|текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок28 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }}
|текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | ([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | ([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }}
|текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | ({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | ; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е место]] }}) }}
|викиданные29 =
|метка30 = [[Названия жителей]]
|текст30 = {{{Этнохороним|}}}
|викиданные30 =
|метка31 = [[Валюта]]
|текст31 = {{{Валюта|}}}
|викиданные31 = P38
|метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]]
|текст32 = {{{Домен|}}}{{{Домены|}}}
|викиданные32 = P78
|метка33 = [[ISO 3166-1|Код ISO]]
|текст33 =
|викиданные33 = P297
|метка34 = [[Список кодов МОК|Код МОК]]
|текст34 =
|викиданные34 = P984
|метка35 = [[Список телефонных кодов стран|Телефонный код]]
|текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }}
|викиданные35 = P474
|метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]]
|текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}}
|викиданные36 = P421
|метка37 = Автомобильное движение
|текст37 = {{{Автомобильное движение|}}}
|викиданные37 = P1622
|текст38 = {{{Примечания|}}}
|стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{карточка/Викисклад|from={{{from|}}}}}
}}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{lat_deg|}}}
| {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}}
| {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }}
}}<!--
-->{{#switch: {{{Статус|}}}
| Виртуальное
| виртуальное = [[Категория:Виртуальные государства]]
| Непризнанное
| непризнанное = [[Категория:Непризнанные государства]]
| Частично признанное
| частично признанное = [[Категория:Частично признанные государства]]
| особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }}
| [[Категория:Государства по алфавиту]]
}}<!--
-->{{Государство/Викиданные}}
}}<noinclude>{{doc}}</noinclude>
d5532838af5967020fc4f653452458ba05aea4cf